自定义构建的 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 收藏
-
478 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
课程推荐
更多>
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习