来自云龙湖轮廓分明的月亮 发表于 2025-1-25 19:08:39

【GoLang】使用validator包实现服务端参数校验时自界说错误信息

在C/S架构下,服务端在校验请求参数时,若出现参数错误,要相应给客户端一个错误消息,通常我们会统一相应“参数错误”。https://i-blog.csdnimg.cn/direct/dcf7bb3c4fb74496a87a9fb353c0189c.png
https://i-blog.csdnimg.cn/direct/1a979b0ab87747ca9356398e5effef28.png
但是,如果只是一味的提示参数错误,我并不知道具体是哪个参数错了呀!能不能有更具体,更细致的提示信息?比方(账号错误、密码为空、姓名不能包含数字),固然可以,下面我来教你如何使用validator包实现自界说参数错误信息。
validator包下载

validator是开源的第三方包,专门用于进行参数校验。我们先下载一下:
   github.com/go-playground/validator/v10
打上布局体标签

validator包提供了布局体标签选项,我们可以为想要进行参数校验的字段打上标签,之后就会以此标签作为校验标准。
https://i-blog.csdnimg.cn/direct/b98842028ff5441e83dae496d7e2c1a0.png
进行参数校验

Struct方法会检验其参数s(假设参数s为布局体)是否符合布局体标签的标准(上文提到的validate标签)。若不符合标准,则将具体不符合的情况作为err返回。
https://i-blog.csdnimg.cn/direct/d22c1f3f8a024e9681beff80bb57846b.png
现在我们模仿一遍请求参数错误时的场景
package main

import (
        "fmt"
        "github.com/go-playground/validator/v10"
)

type RegisterModel struct {
        Username string `validate:"required,numeric"`               // numeric 必须是数字
        Password string `validate:"required,alphanum"`            // alphanum 必须是数字字母组合
        Name   string `validate:"required"`                     // required 必须非空
        Age      int    `validate:"required,gte=0,lte=100,numeric"` // gte, lte 为最大最小值
        Gender   string `validate:"required,oneof=男 女"`             // oneof 必须为其中的某个值
}

func main() {
        // 模拟客户端发来的请求参数
        model := RegisterModel{
                Username: "中文中文",        // 故意让其不符合标准
                Password: "123哈哈哈",
                Name:   "",
        }

        // 用validator包进行校验
        validate := validator.New()        // 先new一个对象
        err := validate.Struct(model)        // 通过对象调用Struct方法
        if err != nil {
                fmt.Println(err)
        }
}

打印错误信息,可以发现其中包含了 不符合标准的字段 和 不符合标准的标签(下文将其统称为错误字段、错误标签)https://i-blog.csdnimg.cn/direct/3fe900f819384dd98b680aebe1206476.png
有了这些信息,就方便我们进行自界说参数信息了!但是仅有这些还不够,我们必要将这些信息各自提取到变量中。
将错误字段和错误标签提取出来

validator包里也给我们提供了方法:我们先将得到的err断言成validator.ValidationErrors,其本质是一个布局体切片,布局体中包含了错误字段和错误标签。接着我们遍历该布局体,即可拿到错误字段和错误标签。
                // 将err中包含的字段和标签提取出来
                if validationErrors, ok := err.(validator.ValidationErrors); ok {        // 将err断言
                        for _, vErr := range validationErrors { // validationErrors 是一个结构体切片
                                fmt.Println(vErr.StructField(), vErr.Tag())        // 打印得到的错误字段和错误标签
                        }
                }
https://i-blog.csdnimg.cn/direct/e981683d3a8546369c90626becd52bdd.png
实战如下
package main

import (
        "fmt"
        "github.com/go-playground/validator/v10"
)

type RegisterModel struct {
        Username string `validate:"required,numeric"`               // numeric 必须是数字
        Password string `validate:"required,alphanum"`            // alphanum 必须是数字字母组合
        Name   string `validate:"required"`                     // required 必须非空
        Age      int    `validate:"required,gte=0,lte=100,numeric"` // gte, lte 为最大最小值
        Gender   string `validate:"required,oneof=男 女"`             // oneof 必须为其中的某个值
}

func main() {
        // 模拟客户端发来的请求参数
        model := RegisterModel{
                Username: "中文中文",
                Password: "123哈哈哈",
                Name:   "",
        }

        // 用validator包进行校验

        validate := validator.New()

        err := validate.Struct(model)
        if err != nil {
                fmt.Println(err)
                // 将err中包含的字段和标签提取出来
                if validationErrors, ok := err.(validator.ValidationErrors); ok {
                        for _, vErr := range validationErrors { // validationErrors 是一个结构体切片
                                vErr.StructField()
                                vErr.Tag()
                                fmt.Println(vErr.StructField(), vErr.Tag())
                        }
                }
        }
}

https://i-blog.csdnimg.cn/direct/63533906107b4fc19e689858a9d257ac.png
现在我们有了错误字段和错误标签,我们就可以自界说参数错误信息了。
自界说参数错误信息

这里我用的方法是我自创的,比较土,紧张是在map中通不对误字段、错误标签映射到自界说的信息。
起首声明两个map
https://i-blog.csdnimg.cn/direct/a002f7f06637495eb9a086d64234c48b.png
然后在遍历中通过map的映射关系获取到自界说信息。
https://i-blog.csdnimg.cn/direct/021fdc18c57c4936a2db401fc0aba216.png
实战:
package main

import (
        "fmt"
        "github.com/go-playground/validator/v10"
)

type RegisterModel struct {
        Username string `validate:"required,numeric"`               // numeric 必须是数字
        Password string `validate:"required,alphanum"`            // alphanum 必须是数字字母组合
        Name   string `validate:"required"`                     // required 必须非空
        Age      int    `validate:"required,gte=0,lte=100,numeric"` // gte, lte 为最大最小值
        Gender   string `validate:"required,oneof=男 女"`             // oneof 必须为其中的某个值
}

// 错误标签map
var tagMsg = mapstring{
        "no-whitespace": "不能含有空格", // 键为结构体标签,值为自定义的错误信息
        "required":      "不能为空",
        "numeric":       "必须是数字",
        "alphanum":      "只能包含字母和数字",
        "oneof":         "错误",
        "lte":         "超出限定范围",
        "gte":         "超出限定范围",
}

// 错误字段map
var fieldMsg = mapstring{
        "Username":   "账号", // 键为字段名,值为自定义的字段名信息
        "Password":   "密码",
        "Name":       "姓名",
        "Age":      "年龄",
        "Gender":   "性别",
        "Permission": "权限",
}

func main() {
        // 模拟客户端发来的请求参数
        model := RegisterModel{
                Username: "中文中文",
                Password: "123哈哈哈",
                Name:   "",
        }

        // 用validator包进行校验

        validate := validator.New()

        err := validate.Struct(model)
        if err != nil {
                fmt.Println(err)
                // 将err中包含的字段和标签提取出来
                if validationErrors, ok := err.(validator.ValidationErrors); ok {
                        for _, vErr := range validationErrors { // validationErrors 是一个结构体切片
                                fmt.Println(fieldMsg + tagMsg)
                        }
                }
        }
}
输出结果:https://i-blog.csdnimg.cn/direct/258f7919fbd84cef967f6f9a0e21c0a6.png
至此,我们就用validator包实现自界说参数错误信息。
感谢浏览,如有不对欢迎指出。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【GoLang】使用validator包实现服务端参数校验时自界说错误信息