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

打印 上一主题 下一主题

主题 982|帖子 982|积分 2956

在C/S架构下,服务端在校验请求参数时,若出现参数错误,要相应给客户端一个错误消息,通常我们会统一相应“参数错误”。


但是,如果只是一味的提示参数错误,我并不知道具体是哪个参数错了呀!能不能有更具体,更细致的提示信息?比方(账号错误、密码为空、姓名不能包含数字),固然可以,下面我来教你如何使用validator包实现自界说参数错误信息。
validator包下载

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

validator包提供了布局体标签选项,我们可以为想要进行参数校验的字段打上标签,之后就会以此标签作为校验标准

进行参数校验

Struct方法会检验其参数s(假设参数s为布局体)是否符合布局体标签的标准(上文提到的validate标签)。若不符合标准,则将具体不符合的情况作为err返回。

现在我们模仿一遍请求参数错误时的场景
  1. package main
  2. import (
  3.         "fmt"
  4.         "github.com/go-playground/validator/v10"
  5. )
  6. type RegisterModel struct {
  7.         Username string `validate:"required,numeric"`               // numeric 必须是数字
  8.         Password string `validate:"required,alphanum"`              // alphanum 必须是数字字母组合
  9.         Name     string `validate:"required"`                       // required 必须非空
  10.         Age      int    `validate:"required,gte=0,lte=100,numeric"` // gte, lte 为最大最小值
  11.         Gender   string `validate:"required,oneof=男 女"`             // oneof 必须为其中的某个值
  12. }
  13. func main() {
  14.         // 模拟客户端发来的请求参数
  15.         model := RegisterModel{
  16.                 Username: "中文中文",        // 故意让其不符合标准
  17.                 Password: "123哈哈哈",
  18.                 Name:     "",
  19.         }
  20.         // 用validator包进行校验
  21.         validate := validator.New()        // 先new一个对象
  22.         err := validate.Struct(model)        // 通过对象调用Struct方法
  23.         if err != nil {
  24.                 fmt.Println(err)
  25.         }
  26. }
复制代码
打印错误信息,可以发现其中包含了 不符合标准的字段 和 不符合标准的标签(下文将其统称为错误字段、错误标签)

有了这些信息,就方便我们进行自界说参数信息了!但是仅有这些还不够,我们必要将这些信息各自提取到变量中。
将错误字段和错误标签提取出来

validator包里也给我们提供了方法:我们先将得到的err断言成validator.ValidationErrors,其本质是一个布局体切片,布局体中包含了错误字段和错误标签。接着我们遍历该布局体,即可拿到错误字段和错误标签。
  1.                 // 将err中包含的字段和标签提取出来
  2.                 if validationErrors, ok := err.(validator.ValidationErrors); ok {        // 将err断言
  3.                         for _, vErr := range validationErrors { // validationErrors 是一个结构体切片
  4.                                 fmt.Println(vErr.StructField(), vErr.Tag())        // 打印得到的错误字段和错误标签
  5.                         }
  6.                 }
复制代码

实战如下
  1. package main
  2. import (
  3.         "fmt"
  4.         "github.com/go-playground/validator/v10"
  5. )
  6. type RegisterModel struct {
  7.         Username string `validate:"required,numeric"`               // numeric 必须是数字
  8.         Password string `validate:"required,alphanum"`              // alphanum 必须是数字字母组合
  9.         Name     string `validate:"required"`                       // required 必须非空
  10.         Age      int    `validate:"required,gte=0,lte=100,numeric"` // gte, lte 为最大最小值
  11.         Gender   string `validate:"required,oneof=男 女"`             // oneof 必须为其中的某个值
  12. }
  13. func main() {
  14.         // 模拟客户端发来的请求参数
  15.         model := RegisterModel{
  16.                 Username: "中文中文",
  17.                 Password: "123哈哈哈",
  18.                 Name:     "",
  19.         }
  20.         // 用validator包进行校验
  21.         validate := validator.New()
  22.         err := validate.Struct(model)
  23.         if err != nil {
  24.                 fmt.Println(err)
  25.                 // 将err中包含的字段和标签提取出来
  26.                 if validationErrors, ok := err.(validator.ValidationErrors); ok {
  27.                         for _, vErr := range validationErrors { // validationErrors 是一个结构体切片
  28.                                 vErr.StructField()
  29.                                 vErr.Tag()
  30.                                 fmt.Println(vErr.StructField(), vErr.Tag())
  31.                         }
  32.                 }
  33.         }
  34. }
复制代码

现在我们有了错误字段和错误标签,我们就可以自界说参数错误信息了。
自界说参数错误信息

这里我用的方法是我自创的,比较土,紧张是在map中通不对误字段、错误标签映射到自界说的信息。
起首声明两个map

然后在遍历中通过map的映射关系获取到自界说信息。

实战:
  1. package main
  2. import (
  3.         "fmt"
  4.         "github.com/go-playground/validator/v10"
  5. )
  6. type RegisterModel struct {
  7.         Username string `validate:"required,numeric"`               // numeric 必须是数字
  8.         Password string `validate:"required,alphanum"`              // alphanum 必须是数字字母组合
  9.         Name     string `validate:"required"`                       // required 必须非空
  10.         Age      int    `validate:"required,gte=0,lte=100,numeric"` // gte, lte 为最大最小值
  11.         Gender   string `validate:"required,oneof=男 女"`             // oneof 必须为其中的某个值
  12. }
  13. // 错误标签map
  14. var tagMsg = map[string]string{
  15.         "no-whitespace": "不能含有空格", // 键为结构体标签,值为自定义的错误信息
  16.         "required":      "不能为空",
  17.         "numeric":       "必须是数字",
  18.         "alphanum":      "只能包含字母和数字",
  19.         "oneof":         "错误",
  20.         "lte":           "超出限定范围",
  21.         "gte":           "超出限定范围",
  22. }
  23. // 错误字段map
  24. var fieldMsg = map[string]string{
  25.         "Username":   "账号", // 键为字段名,值为自定义的字段名信息
  26.         "Password":   "密码",
  27.         "Name":       "姓名",
  28.         "Age":        "年龄",
  29.         "Gender":     "性别",
  30.         "Permission": "权限",
  31. }
  32. func main() {
  33.         // 模拟客户端发来的请求参数
  34.         model := RegisterModel{
  35.                 Username: "中文中文",
  36.                 Password: "123哈哈哈",
  37.                 Name:     "",
  38.         }
  39.         // 用validator包进行校验
  40.         validate := validator.New()
  41.         err := validate.Struct(model)
  42.         if err != nil {
  43.                 fmt.Println(err)
  44.                 // 将err中包含的字段和标签提取出来
  45.                 if validationErrors, ok := err.(validator.ValidationErrors); ok {
  46.                         for _, vErr := range validationErrors { // validationErrors 是一个结构体切片
  47.                                 fmt.Println(fieldMsg[vErr.StructField()] + tagMsg[vErr.Tag()])
  48.                         }
  49.                 }
  50.         }
  51. }
复制代码
输出结果:

至此,我们就用validator包实现自界说参数错误信息。
感谢浏览,如有不对欢迎指出。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

来自云龙湖轮廓分明的月亮

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表