Solon v4.0.4

snack4 - JsonSchema 应用参考

</> markdown
2026年8月3日 下午3:13:41

snack4-jsonschema 提供从 Java 类型生成 JSON Schema,以及参照 Schema 校验数据的能力。支持 JSON Schema 的 draft-07 / 2019-09 / 2020-12 草案版本。

1、添加依赖

<dependency>
  <groupId>org.noear</groupId>
  <artifactId>snack4-jsonschema</artifactId>
  <version>最新版</version>
</dependency>

2、构建 JsonSchema

通过 JsonSchema.builder() 构建,并配置草案版本与生成行为:

// 默认:DRAFT_7
JsonSchema jsonSchema = JsonSchema.builder().build();

// 自定义配置
JsonSchema jsonSchema2 = JsonSchema.builder()
        .version(SchemaVersion.DRAFT_2020_12)   // 草案版本
        .enableDefinitions(true)                // 启用 definitions/$defs 定义规范
        .printVersion(true)                     // 输出中打印 $schema 版本标识
        .build();

SchemaVersion 枚举:

枚举标识
DRAFT_7http://json-schema.org/draft-07/schema#
DRAFT_2019_09https://json-schema.org/draft/2019-09/schema
DRAFT_2020_12https://json-schema.org/draft/2020-12/schema

启用 enableDefinitions(true) 时:draft-07 使用 definitions 关键字,2019-09 / 2020-12 使用 $defs 关键字。

3、从类型生成 Schema

//方式一:通过 JsonSchema 生成
ONode jsonSchemaNode = jsonSchema.generate(BookModel.class);

//方式二:创建生成器
JsonSchemaGenerator generator = jsonSchema.createGenerator(BookModel.class);
ONode jsonSchemaNode2 = generator.generate();

BookModel 为例:

public class BookModel {
    public int id;

    @ONodeAttr(name = "name")
    public String bookname;

    @ONodeAttr(description = "备注")
    public String note;
}

生成结果(示意):

{
  "type": "object",
  "properties": {
    "id": { "type": "integer" },
    "name": { "type": "string" },
    "note": { "type": "string", "description": "备注" }
  },
  "required": ["id", "name", "note"]
}

生成规则要点:

  • 字段默认均视为 required(可通过 @ONodeAttr(required=false) 调整)
  • @ONodeAttr(name=...) 可改变属性名
  • @ONodeAttr(description=...) 生成 description
  • @ONodeAttr(title=...) 生成 title
  • @ONodeAttr(defaultValue=...) 生成 default
  • @ONodeAttr(format=...) 生成时间格式约束
  • @ONodeAttr(ignore=true)transient 字段跳过
  • 集合生成 array + items,Map 生成 object + additionalProperties
  • 循环引用:未启用 definitions 时生成占位说明节点;启用后生成 $ref 引用

4、参照 Schema 验证数据

校验失败抛出 JsonSchemaException

//参照类型验证(内部先生成 schema)
jsonSchema.validate(BookModel.class, ONode.ofJson("{\"id\":1,\"name\":\"x\"}"));

//参照已生成的 schema 节点验证
jsonSchema.validate(jsonSchemaNode, ONode.ofJson("{\"id\":1,\"name\":\"x\"}"));

//方式二:创建验证器(可复用)
JsonSchemaValidator validator = jsonSchema.createValidator(jsonSchemaNode);
validator.validate(ONode.ofJson("{\"id\":1,\"name\":\"x\"}"));

5、支持的校验关键字

关键字说明
type类型校验
enum枚举值校验
required必填字段
minLength / maxLength / pattern字符串约束
minimum / maximum / exclusiveMinimum / exclusiveMaximum数值约束
minItems / maxItems数组项数约束
items数组项 schema
additionalProperties额外属性约束
propertyNames属性名约束
patternProperties模式属性约束
allOf / anyOf / oneOf条件组合(allOf 编译期合并;anyOf 至少一个命中;oneOf 恰好一个命中)
$ref本地引用(#/... JSON Pointer,支持 ~0/~1 转义与数组索引)

6、自定义映射

通过 addSchemaMapper / addTypeMapper 定制类型的生成行为:

jsonSchema.addSchemaMapper(BookModel.class, (typeEggg, target) -> {
    return target.set("type", "object").set("description", "custom schema");
});

jsonSchema.addTypeMapper(SomeType.class, typeEggg -> {
    //把类型映射为其它类型后继续生成
    return ...;
});

7、使用示例

public class JsonSchemaDemo {
    public void case1() {
        JsonSchema jsonSchema = JsonSchema.builder().build();

        //生成 schema
        ONode jsonSchemaNode = jsonSchema.generate(BookModel.class);

        //参照类型验证
        jsonSchema.validate(BookModel.class, ONode.ofJson("{}"));

        //参照 schema 节点验证
        jsonSchema.validate(jsonSchemaNode, ONode.ofJson("{}"));
    }
}