---
# System prepended metadata

title: '[Java] JSON Schema (v2020-12)'
tags: [Json, Java]

---

# [Java] JSON Schema (v2020-12)
[TOC]

## type
允許的型態有 
* object (需要搭配 properties 定義 Key-value)
* array (需要搭配 items 定義 array element)
* string
* integer (整數)
* number (允許小數)
* boolean
* null


範例：
表示只允許字串
```=json
"type": "string"
```
表示允許字串及null
```=json
"type": ["string", "null"]
```
## string length
```
x ≥ minLength
x ≤ maxLength
```

## number range
檢查最小值、最大值，如有小數建議搭配 multipleOf，可以限制範圍及小數格式。
```
x ≥ minimum
x > exclusiveMinimum
x ≤ maximum
x < exclusiveMaximum
```
範例：
```=json
"price": {
    "type": "integer",
    "description": "允許0~99的數值",
    "minimum": 0,
    "maximum": 99
},
"discount": {
    "type": "number",
    "description": "允許0~100的數值，可到小數兩位",
    "minimum": 0,
    "maximum": 100,
    "multipleOf": 0.01
},
```

## format
`"format": "date-time"` 依照 RFC 3339 規定必須是像 `"2025-03-03T17:52:26Z"` 或 `"2025-03-03T17:52:26+08:00"` 的 ISO 8601 格式（帶有 T 與時區資訊）
```=json
"create_date": {
    "type": "string",
    "format": "date-time"
},
```

## pattern
數字及字串都能使用正規表達式
範例：
字串要檢查日期格式
```=json
"birthday": {
    "type": "string",
    "pattern": "^(\\d{8}|00000000)$",
    "description": "日期格式為 yyyyMMdd 或預設 00000000"
},
```
數字要檢查長度符合8 (單純檢查數值大小建議使用 minimum 或 maximum)
```=json
"serial_no": {
    "type": "integer",
    "pattern": "^\\d{8}$",
    "description": "產品編號必須是8碼數字"
},
```

## required
用於 object 型態，檢查有沒有缺少的 key，key不能用正則表達式

範例： 
```=json
"employee": {
    "type": "object",
    "required": [ "name" ],
    "properties": {
        "name": { 
            "type": "string",
            "maxLength": 20
        },
        "memo": { 
            "type": ["string", "null"], 
            "maxLength": 150
        },
        ...
},
```
以上面的 schema 來看，A的資料會通過驗證，但B會拋出錯誤訊息
A
```=json
{
  "employee": {
    "name": "Alice",
    "memo": "備註內容"
  }
}
```
B
```=json
{
  "employee": {
    "memo": "備註內容"
  }
}
```

## additionalProperties
用於 object 型態，檢查 keys 有沒有符合，可用來檢查有沒有多餘欄位

| 設定 | 說明 |
| --- | --- |
| `true`（預設） | 允許出現未定義的欄位 |
| `false` | 禁止所有未定義欄位（常用來防止多餘欄位） |
| `schema` | 自訂「未列出的欄位」的格式，例如所有多餘欄位都必須是 string <br> `"additionalProperties": { "type": "string" }` |

範例：
```=json
{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age":  { "type": "integer" }
  },
  "required": ["name", "age"],
  "additionalProperties": false
},
```

## patternProperties
如果有多個相似的 key 可以用正規表達式定義欄位名稱，如：XYZ-1、XYZ-05、XYZ-20...等，可以用 "^XYZ-[0-9]{1,3}$"
```=json
{
  "name": "John Doe",
  "age": 25,
  "XYZ-1": "HR",
  "XYZ-05": 2345,
  "XYZ-20": null
}
```
```=json
{
  "type":"object",
  "patternProperties": {
    "^XYZ-[0-9]{1,3}$": {
      "type": ["string". "integer", "null"]
    }
  }
}
```


參考資料：
[JSON Schema v2020-12](https://json-schema.org/draft/2020-12/schema)
[Json Schema Validator](https://www.jsonschemavalidator.net/)
[JSON Schema - Creating your first schema](https://json-schema.org/learn/getting-started-step-by-step)
[驗證資料的好幫手 - JSON Schema Validator #2](https://github.com/Hsueh-Jen/blog/issues/2)