---
title: "snack4 - JsonSchema 应用参考"
---


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

### 1、添加依赖

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

### 2、构建 JsonSchema

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

```java
// 默认：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_7` | `http://json-schema.org/draft-07/schema#` |
| `DRAFT_2019_09` | `https://json-schema.org/draft/2019-09/schema` |
| `DRAFT_2020_12` | `https://json-schema.org/draft/2020-12/schema` |

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

### 3、从类型生成 Schema

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

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

以 `BookModel` 为例：

```java
public class BookModel {
    public int id;

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

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

生成结果（示意）：

```json
{
  "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`。

```java
//参照类型验证（内部先生成 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` 定制类型的生成行为：

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

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

### 7、使用示例

```java
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("{}"));
    }
}
```
