如何使用Jackson生成带必填字段与默认值的JSON Schema?
Jackson生成带必填声明、默认值的JSON Schema实现方案
原生com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator默认不会自动收集必填字段元数据,也不会读取字段初始默认值,需要通过注解标记+简单的二次Schema处理实现需求,具体操作如下:
1. 给实体类字段添加注解标记
首先在需要设为必填的字段上添加@JsonProperty(required = true)注解;由于Jackson无法直接读取Java字段初始化时赋的默认值(该值属于类实例运行时数据,不会生成在类的元数据中),需要通过@JsonProperty的defaultValue属性显式声明默认值。
修改后的DBUser类代码:
import com.fasterxml.jackson.annotation.JsonProperty; public class DBUser { @JsonProperty(required = true, defaultValue = "stu") private String database = "stu"; @JsonProperty(required = true) private int role; @JsonProperty(required = true) private String username; private String password; // 原有set、get方法保持不变 }
2. 自定义Schema生成处理逻辑
原生生成器生成基础Schema结构后,通过反射读取类字段上的注解,填充根节点的required数组,同时给对应属性节点添加default字段即可,完整实现代码:
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jsonSchema.JsonSchema; import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator; import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; public class CustomSchemaGenerator { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); JsonSchemaGenerator generator = new JsonSchemaGenerator(mapper); JsonSchema jsonSchema = generator.generateSchema(DBUser.class); if (jsonSchema.isObjectSchema()) { ObjectSchema objectSchema = jsonSchema.asObjectSchema(); List<String> requiredList = new ArrayList<>(); // 遍历类所有字段读取注解配置 Class<DBUser> targetClass = DBUser.class; for (Field field : targetClass.getDeclaredFields()) { JsonProperty annotation = field.getAnnotation(JsonProperty.class); String fieldName = field.getName(); // 收集必填字段 if (annotation != null && annotation.required()) { requiredList.add(fieldName); } // 写入字段默认值 if (annotation != null && !annotation.defaultValue().isEmpty()) { JsonSchema propSchema = objectSchema.getProperties().get(fieldName); propSchema.setDefault(annotation.defaultValue()); } } // 给根节点绑定必填列表 objectSchema.setRequired(requiredList.toArray(new String[0])); } // 输出最终Schema System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema)); } }
生成结果示例
运行上述代码后,输出的Schema完全符合需求:
{ "type" : "object", "id" : "urn:jsonschema:DBUser", "required" : [ "database", "role", "username" ], "properties" : { "database" : { "type" : "string", "default" : "stu" }, "role" : { "type" : "integer" }, "username" : { "type" : "string" }, "password" : { "type" : "string" } } }
补充说明
- 如果不想手动编写反射处理逻辑,可以替换使用支持JSR-303校验注解的Jackson JSON Schema扩展实现,这类实现可以自动识别
@NotNull等常用校验注解生成required规则,部分实现也支持直接读取字段初始值作为默认值,无需额外注解声明。 - 给基本数值类型、布尔类型字段配置defaultValue时,直接传入对应值的字符串即可,Jackson序列化时会自动转换为正确的JSON类型。
内容的提问来源于stack exchange,提问作者Aws AbuObeid
相关产品推荐
相关产品推荐

