什么是JSON验证
JSON验证是确保JSON数据符合预定义结构和规则的过程。通过验证,我们可以:
- • 确保数据格式正确
- • 验证必填字段存在
- • 检查数据类型匹配
- • 应用业务规则约束
- • 提供清晰的错误信息
验证的好处
- • 提高数据质量
- • 减少运行时错误
- • 增强API健壮性
- • 改善用户体验
- • 便于调试和维护
验证时机
- • 客户端输入验证
- • API接口数据校验
- • 数据库存储前验证
- • 配置文件加载时
- • 数据导入导出过程
JSON Schema基础
基本Schema结构
简单Schema示例
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/user.schema.json",
"title": "User",
"description": "用户信息结构",
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
}
},
"required": ["id", "name", "email"],
"additionalProperties": false
}对应的有效JSON数据
{
"id": 123,
"name": "张三",
"email": "zhangsan@example.com",
"age": 28
}无效JSON数据示例
{
"id": "abc", // 错误:应为整数
"name": "", // 错误:长度不能为0
"email": "invalid-email", // 错误:邮箱格式不正确
"age": -5 // 错误:年龄不能为负数
}Schema关键字说明
基础关键字
$schema指定Schema版本$idSchema的唯一标识符titleSchema的标题descriptionSchema的描述type数据类型约束关键字
required必填字段列表properties对象属性定义minimum数字最小值maximum数字最大值minLength字符串最小长度数据类型验证
字符串验证 (string)
验证约束
- • minLength / maxLength - 长度限制
- • pattern - 正则表达式匹配
- • format - 预定义格式 (email, date, uri等)
- • enum - 枚举值限制
Schema示例
{
"type": "string",
"minLength": 3,
"maxLength": 50,
"pattern": "^[A-Za-z0-9]+$",
"format": "email"
}✅ 有效值
"user@example.com"❌ 无效值
"ab" // 长度不足 "user@" // 格式不正确
数字验证 (number/integer)
验证约束
- • minimum / maximum - 值范围
- • exclusiveMinimum / exclusiveMaximum - 排他性范围
- • multipleOf - 倍数约束
- • integer vs number 类型区分
Schema示例
{
"type": "integer",
"minimum": 1,
"maximum": 100,
"multipleOf": 5
}✅ 有效值
15, 25, 50❌ 无效值
0 // 小于最小值 150 // 超过最大值 13 // 不是5的倍数
布尔值验证 (boolean)
验证约束
- • 只接受 true 或 false
- • 不接受字符串 "true"/"false"
- • 不接受数字 1/0
Schema示例
{
"type": "boolean"
}✅ 有效值
true, false❌ 无效值
"true" // 字符串 1 // 数字 null // 空值
数组验证 (array)
验证约束
- • items - 数组元素类型
- • minItems / maxItems - 长度限制
- • uniqueItems - 唯一性约束
- • additionalItems - 额外元素控制
Schema示例
{
"type": "array",
"items": {"type": "string"},
"minItems": 1,
"maxItems": 5,
"uniqueItems": true
}✅ 有效值
["a", "b", "c"]❌ 无效值
[] // 长度不足 ["a", "a"] // 不唯一 [1, 2, 3] // 类型错误
对象验证 (object)
验证约束
- • properties - 属性定义
- • required - 必填属性
- • additionalProperties - 额外属性控制
- • minProperties / maxProperties - 属性数量限制
Schema示例
{
"type": "object",
"properties": {
"name": {"type": "string"}
},
"required": ["name"],
"additionalProperties": false
}✅ 有效值
{"name": "张三"}❌ 无效值
{} // 缺少必填字段
{"name": "张三", "age": 25} // 不允许额外属性高级验证规则
条件验证 (if/then/else)
{
"type": "object",
"properties": {
"type": {"type": "string", "enum": ["person", "company"]},
"name": {"type": "string"},
"age": {"type": "integer"},
"employees": {"type": "integer"}
},
"if": {
"properties": {"type": {"const": "person"}}
},
"then": {
"required": ["name", "age"],
"not": {"required": ["employees"]}
},
"else": {
"required": ["name", "employees"],
"not": {"required": ["age"]}
}
}根据 type 字段的值,动态要求不同的必填字段。
组合验证 (allOf/anyOf/oneOf)
allOf (且)
{
"allOf": [
{"minimum": 10},
{"maximum": 50},
{"multipleOf": 5}
]
}必须同时满足所有条件
anyOf (或)
{
"anyOf": [
{"type": "string"},
{"type": "number"}
]
}满足任一条件即可
oneOf (异或)
{
"oneOf": [
{"minimum": 0},
{"maximum": 0}
]
}只能满足其中一个条件
自定义格式验证
内置格式
email邮箱地址date日期 (YYYY-MM-DD)date-time日期时间 (ISO 8601)uriURI地址uuidUUID标识符正则表达式验证
{
"type": "string",
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
"description": "YYYY-MM-DD格式的日期"
}
{
"type": "string",
"pattern": "^1[3-9]\d{9}$",
"description": "中国手机号码"
}错误处理策略
验证错误信息结构
{
"valid": false,
"errors": [
{
"instancePath": "/user/email",
"schemaPath": "#/properties/user/properties/email/format",
"keyword": "format",
"params": {"format": "email"},
"message": "must match format \"email\"",
"data": "invalid-email"
},
{
"instancePath": "/user/age",
"schemaPath": "#/properties/user/properties/age/minimum",
"keyword": "minimum",
"params": {"minimum": 0},
"message": "must be >= 0",
"data": -5
}
]
}错误信息字段说明
- •
instancePath: 错误数据的路径 - •
schemaPath: 对应的Schema路径 - •
keyword: 失败的验证关键字 - •
params: 验证参数 - •
message: 错误描述 - •
data: 实际的错误数据
用户友好的错误处理
- • 将技术错误转换为用户可理解的信息
- • 提供修复建议
- • 按字段分组显示错误
- • 高亮显示错误位置
- • 提供示例正确格式
❌ 糟糕的错误信息
"must match format 'email'""data.age must be >= 0"问题:技术术语,用户难以理解
✅ 良好的错误信息
"邮箱格式不正确,请输入有效的邮箱地址""年龄不能为负数,请输入0或正整数"优点:清晰明了,提供解决方案
实用示例
用户注册表单验证
Schema定义
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"username": {
"type": "string",
"minLength": 3,
"maxLength": 20,
"pattern": "^[a-zA-Z0-9_]+$"
},
"email": {
"type": "string",
"format": "email"
},
"password": {
"type": "string",
"minLength": 8,
"pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)"
},
"confirmPassword": {
"type": "string"
},
"age": {
"type": "integer",
"minimum": 13,
"maximum": 120
},
"terms": {
"type": "boolean",
"const": true
}
},
"required": ["username", "email", "password", "confirmPassword", "terms"]
}验证示例
✅ 有效数据
{
"username": "user123",
"email": "user@example.com",
"password": "SecurePass123",
"confirmPassword": "SecurePass123",
"age": 25,
"terms": true
}❌ 无效数据
{
"username": "ab", // 太短
"email": "invalid-email", // 格式错误
"password": "123", // 不符合复杂度要求
"age": 12, // 年龄不足
"terms": false // 必须同意条款
}API响应数据验证
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["success", "error"]
},
"data": {
"type": "object"
},
"error": {
"type": "object",
"properties": {
"code": {"type": "string"},
"message": {"type": "string"}
}
},
"timestamp": {
"type": "string",
"format": "date-time"
}
},
"required": ["status", "timestamp"],
"if": {
"properties": {"status": {"const": "success"}}
},
"then": {
"required": ["data"],
"not": {"required": ["error"]}
},
"else": {
"required": ["error"],
"not": {"required": ["data"]}
}
}根据状态字段动态验证响应结构,成功时包含data,失败时包含error。
工具和库推荐
验证库
AjvJavaScript
最快的JSON Schema验证器
高性能完整的Schema支持自定义关键字
jsonschemaPython
Python标准JSON Schema库
易于使用详细错误信息CLI工具
go-jsonschemaGo
Go语言JSON Schema验证
类型安全高性能零依赖