如何在Go语言中用gojsonschema实现自定义JSON校验错误信息?
在gojsonschema中获取自定义错误信息
gojsonschema默认不会自动识别你在JSON Schema中定义的messages字段,要获取自定义错误提示,需要手动关联schema中的自定义信息和校验错误,具体步骤如下:
1. 提取Schema中的自定义错误信息
先将JSON Schema解析为map结构,遍历提取所有字段的自定义messages,构建一个可快速查找的映射表,键格式为字段路径.校验关键字(比如productId.Age.minimum),值为对应的自定义提示文本。
2. 执行校验并替换错误信息
执行JSON校验后,遍历返回的错误列表,通过错误对象的Field()(获取字段路径)和Key()(获取校验失败的关键字,如minimum)拼接查找键,从映射表中匹配自定义提示,匹配成功则替换默认错误信息,否则保留原信息。
代码示例
import ( "encoding/json" "fmt" "github.com/xeipuuv/gojsonschema" ) func main() { // 定义包含自定义messages的JSON Schema schemaBytes := []byte(`{ "type": "object", "properties": { "productId": { "type": "object", "properties": { "Age": { "type": "integer", "minimum": 10, "messages": { "minimum": "This person is too young" } } } } } }`) // 解析Schema,提取自定义错误信息映射 var schemaMap map[string]interface{} if err := json.Unmarshal(schemaBytes, &schemaMap); err != nil { panic(err) } customMsgMap := make(map[string]string) // 手动遍历Schema结构提取messages(复杂Schema需递归遍历) productIdProps := schemaMap["properties"].(map[string]interface{})["productId"].(map[string]interface{})["properties"].(map[string]interface{}) ageField := productIdProps["Age"].(map[string]interface{}) if msgContainer, ok := ageField["messages"].(map[string]interface{}); ok { for ruleKey, msg := range msgContainer { customMsgMap["productId.Age."+ruleKey] = msg.(string) } } // 待校验的JSON数据 dataBytes := []byte(`{ "productId": { "Age": 5 } }`) // 执行校验 schemaLoader := gojsonschema.NewBytesLoader(schemaBytes) dataLoader := gojsonschema.NewBytesLoader(dataBytes) result, err := gojsonschema.Validate(schemaLoader, dataLoader) if err != nil { panic(err) } // 处理错误,替换为自定义提示 if !result.Valid() { for _, errItem := range result.Errors() { lookupKey := errItem.Field() + "." + errItem.Key() if customMsg, exists := customMsgMap[lookupKey]; exists { fmt.Println(customMsg) } else { fmt.Println(errItem) } } } }
关键点说明
ResultError对象的Field()方法返回错误字段的完整路径,Key()方法返回触发错误的校验规则关键字(如minimum、maxLength)。- 如果你的Schema结构复杂(包含嵌套数组、多层对象),需要编写递归函数遍历所有字段的
messages,确保所有自定义提示都被提取到映射表中。 - 无论Schema是从字符串、文件还是其他来源加载,都可以先将其解析为map结构来提取自定义信息。
内容的提问来源于stack exchange,提问作者sid
相关产品推荐
相关产品推荐

