如何使用Golang验证JSON输入?

10
我正在使用Beego框架在Go语言中构建Web应用程序。我必须验证API请求中的传入JSON数据。
我可以将JSON反序列化为结构体,这很好用,但是我也想验证数据。例如,如果类型与结构中的类型不匹配,json.Unmarshal将在第一次出现时返回一个错误。我想对JSON进行验证并获取所有错误。
我已经尝试过https://github.com/thedevsaddam/govalidator ,但是该程序包需要引用请求对象,而在Beego的控制器中无法获得该对象的引用。还有其他可以验证结构体但我想要JSON验证。
编辑:
从控制器的上下文对象中可以找到对请求对象的引用。
func (this *MainController) Post() {
    fmt.Println(this.Ctx.Request)
}

但是,使用JSON解封时仍存在问题。如果类型存在轻微不匹配,json.unmarshal将立即引发异常。我想能够验证类型是否匹配。


这不受标准库支持,所以看起来你是在寻求第三方库?这是SO的离题问题。 - icza
欢迎使用第三方库或任何解决方案。 - anshuraj
1
json.Decoder.Token() 可能会有所帮助,但需要编写相当多的代码。 - Mihai Todor
4个回答

13

6
我们已经使用了 go-playground/validator.v8 来实现类似的功能。你可以使用内置的标签定义数据验证规则(基础内容,如相等、最小/最大等,甚至有一些表达式语言)。除此之外,你还可以添加自定义的验证规则。具体信息请查看文档,希望对你有所帮助。

1

有一个方法checkValid(在encoding/json包中),可以做到这一点。然而,这个方法没有暴露出来。因此,您可以使用相同包中的Unmarshal来检查JSON是否有效。


1
我今天必须这样做,所以我会分享我的解决方案。我创建了一个使用unmarshal函数的函数,根据文本是否返回有效的json来返回true或false:
// isJSON checks that the string value of the field can unmarshall into valid json
func isJSON(s string) bool {
    var j map[string]interface{}
    if err := json.Unmarshal([]byte(s), &j); err != nil {
        return false
    }
    return true
}

然后我使用这个逻辑和验证器包来创建并注册一个自定义的验证标签,我可以在任何结构体中使用它来验证字段是否包含json。您可以使用go playground来检查完整的解决方案并进行实验:

// isJSON checks that the string value of the field can unmarshall into valid json
func isJSON(fl validator.FieldLevel) bool {
    var j map[string]interface{}
    if err := json.Unmarshal([]byte(fl.Field().String()), &j); err != nil {
        return false
    }
    return true
}

// register the function with json tag:
validate.RegisterValidation("json", isJSON)

谢谢,这很有帮助。我已经更新了isJson函数,使其返回errorfunc isJSON(s string) error { var j map[string]interface{} return json.Unmarshal([]byte(s), &j) } - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接