自定义构建的 JSON 模式无法正确验证
来源:stackoverflow
时间:2024-03-17 15:45:31 475浏览 收藏
在自定义构建的 JSON 架构验证中遇到问题,发现它无法正确检测所有字段。即使指定了必需字段和长度限制,它也无法验证这些要求。附加属性的验证也无效。尝试使用 gojsonschema 库,但验证结果不符合预期。提供了自定义架构和 JSON 数据的示例,以说明问题。
问题内容
我有一个自定义构建的 json 架构,它只有几个顶层。这里的问题是它不能 100% 验证所有内容。例如,它只检测 4 个字段中的 2 个,并且必需的字段根本不起作用,附加属性等也不起作用。我正在将此库用于我的 json 架构。
{ "users": { "put": { "definitions": {}, "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://example.com/root.json", "type": "object", "title": "the root schema", "required": [ "displayname", "username", "email", "password" ], "properties": { "displayname": { "$id": "#/properties/displayname", "type": "string", "title": "the displayname schema", "default": "", "examples": [ "" ], "minlength": 3, "maxlength": 24, "pattern": "^(.*)$" }, "username": { "$id": "#/properties/username", "type": "string", "title": "the username schema", "default": "", "examples": [ "" ], "minlength": 3, "maxlength": 15, "pattern": "^(.*)$" }, "email": { "$id": "#/properties/email", "type": "string", "title": "the email schema", "default": "", "examples": [ "" ], "minlength": 7, "pattern": "^(.*)$", "format": "email" }, "password": { "$id": "#/properties/password", "type": "string", "title": "the password schema", "default": "", "examples": [ "" ], "pattern": "^(.*)$" } }, "additionalproperties": false } } }
我正在解析这样的所有内容:
func validate(data interface{}, r *http.request) (interface{}, error) { // convert the data struct to a readable json bytes jsonparams, err := json.marshal(data) if err != nil { return nil, err } // split url segments so we know what part of the api they are accessing modules := strings.split(r.url.string(), "/") modules = modules[(len(modules) - 1):] // read the schema file fileschema, _ := ioutil.readfile("config/schema/schema.json") var object interface{} // unmarshal it so we can choose what schema we specifically want err = json.unmarshal(fileschema, &object) if err != nil { log.fatal(err) } // choose the preferred schema encodedjson, err := json.marshal(object.(map[string]interface{})[strings.join(modules, "") + "s"].(map[string]interface{})[r.method]) if err != nil { log.fatal(err) } // load the json schema schema := gojsonschema.newstringloader(string(encodedjson)) // load the json params document := gojsonschema.newstringloader(string(jsonparams)) // validate the document result, err := gojsonschema.validate(schema, document) if err != nil { return nil, err } if !result.valid() { // map the errors into a new array var errors = make(map[string]string) for _, err := range result.errors() { errors[err.field()] = err.description() } // convert the array to an interface that we can convert to json resultmap := map[string]interface{}{ "success": false, "result": map[string]interface{}{}, "errors": errors, } // convert the interface to a json object errorobject, err := json.marshal(resultmap) if err != nil { return nil, err } return errorobject, nil } return nil, nil } type createparams struct { displayname string username string email string password string } var ( response interface{} status int = 0 ) func create(w http.responsewriter, r *http.request) { status = 0 // parse the request so we can access the query parameters r.parseform() // assign them to the interface variables data := &createparams{ displayname: r.form.get("displayname"), username: r.form.get("username"), email: r.form.get("email"), password: r.form.get("password"), } // validate the json data errors, err := schema.validate(data, r) if err != nil { responsejson := map[string]interface{}{ "success": false, "result": map[string]interface{}{}, } log.fatal(err.error()) response, err = json.marshal(responsejson) status = http.statusinternalservererror } // catch any errors generated by the validator and assign them to the response interface if errors != nil { response = errors status = http.statusbadrequest } // status has not been set yet, so it's safe to assume that everything went fine if status == 0 { responsejson := map[string]interface{}{ "success": true, "result": map[string]interface{} { "displayname": data.displayname, "username": data.username, "email": data.email, "password": nil, }, } response, err = json.marshal(responsejson) status = http.statusok } // we are going to respond with json, so set the appropriate header w.header().set("content-type", "application/json") // write the header and the response w.writeheader(status) w.write(response.([]byte)) }
我这样做的原因是我正在构建一个 rest api,如果 api/auth/user
收到 put 请求,我希望能够专门为“用户”指定数据要求使用 put 方法零件。
知道如何实现这一目标吗?
编辑: 我的 json 数据:
{ "displayname": "1234", "username": "1234", "email": "[email protected]", "password": "123456" }
编辑2: 此数据应该因架构而失败。
{ "DisplayName": "1", // min length is 3 "Username": "", // this field is required but is empty here "Email": "testgmail.com", // not following the email format "Password": "123456111111111111111111111111111111111111111111111" // too long }
解决方案
如果我使用 gojsonschema
手动加载架构和数据,它会按预期工作。我怀疑,由于您以某种复杂的方式加载模式,因此您输入的模式最终会与您期望的有所不同,但由于您的代码示例都是基于 HTTP 的,所以我无法真正亲自测试它.
今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~
声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
最新阅读
更多>
-
139 收藏
-
204 收藏
-
325 收藏
-
477 收藏
-
486 收藏
-
439 收藏
课程推荐
更多>
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习