iris请求数据验证

目录结构

主目录readJsonStructValidation

  1. —— main.go

代码示例

main.go

  1. //包main显示验证器(最新版本9)与Iris的集成。
  2. //您可以在以下网址找到更多这样的示例:https//github.com/go-playground/validator/blob/v9/_examples
  3. package main
  4. import (
  5. "fmt"
  6. "github.com/kataras/iris"
  7. // $ go get gopkg.in/go-playground/validator.v9
  8. "gopkg.in/go-playground/validator.v9"
  9. //"gopkg.in/go-playground/validator.v8"
  10. )
  11. //用户包含用户信息。
  12. type User struct {
  13. FirstName string `json:"fname"`
  14. LastName string `json:"lname"`
  15. Age uint8 `json:"age" validate:"gte=0,lte=130"`
  16. Email string `json:"email" validate:"required,email"`
  17. FavouriteColor string `json:"favColor" validate:"hexcolor|rgb|rgba"`
  18. Addresses []*Address `json:"addresses" validate:"required,dive,required"`
  19. }
  20. //地址包含用户地址信息
  21. type Address struct {
  22. Street string `json:"street" validate:"required"`
  23. City string `json:"city" validate:"required"`
  24. Planet string `json:"planet" validate:"required"`
  25. Phone string `json:"phone" validate:"required"`
  26. }
  27. // Use a single instance of Validate, it caches struct info.
  28. //使用Validate的单个实例,它缓存struct info。
  29. var validate *validator.Validate
  30. func main() {
  31. validate = validator.New()
  32. //为'用户'注册验证
  33. //注意:只需要为'User',validator注册一个非指针类型
  34. //在类型检查期间内部取消引用。
  35. validate.RegisterStructValidation(UserStructLevelValidation, User{})
  36. app := iris.New()
  37. app.Get("/user", func(ctx iris.Context) {
  38. fmt.Println("test")
  39. var user User
  40. if err := ctx.ReadJSON(&user); err != nil {
  41. // 处理错误
  42. fmt.Println(err)
  43. }
  44. //为错误的验证输入返回InvalidValidationError,nil或ValidationErrors([] FieldError)
  45. err := validate.Struct(user)
  46. if err != nil {
  47. //只有在您的代码可以生成时才需要进行此检查
  48. //验证的无效值,例如与nil的接口
  49. //大多数包括我自己的值通常不会有这样的代码。
  50. if _, ok := err.(*validator.InvalidValidationError); ok {
  51. ctx.StatusCode(iris.StatusInternalServerError)
  52. ctx.WriteString(err.Error())
  53. return
  54. }
  55. ctx.StatusCode(iris.StatusBadRequest)
  56. for _, err := range err.(validator.ValidationErrors) {
  57. fmt.Println()
  58. fmt.Println(err.Namespace())
  59. fmt.Println(err.Field())
  60. fmt.Println(err.StructNamespace()) //注册自定义TagNameFunc时可能会有所不同
  61. fmt.Println(err.StructField()) //通过将alt名称传递给ReportError,如下所示
  62. fmt.Println(err.Tag())
  63. fmt.Println(err.ActualTag())
  64. fmt.Println(err.Kind())
  65. fmt.Println(err.Type())
  66. fmt.Println(err.Value())
  67. fmt.Println(err.Param())
  68. fmt.Println()
  69. //或者将它们收集为json对象
  70. //并通过ctx.JSON将收集的错误发送回客户端
  71. // {
  72. // "namespace": err.Namespace(),
  73. // "field": err.Field(),
  74. // "struct_namespace": err.StructNamespace(),
  75. // "struct_field": err.StructField(),
  76. // "tag": err.Tag(),
  77. // "actual_tag": err.ActualTag(),
  78. // "kind": err.Kind().String(),
  79. // "type": err.Type().String(),
  80. // "value": fmt.Sprintf("%v", err.Value()),
  81. // "param": err.Param(),
  82. // }
  83. }
  84. ctx.WriteString("testasdd")
  85. //从这里你可以用你想要的任何语言创建自己的错误信息。
  86. return
  87. }
  88. //将用户保存到数据库
  89. })
  90. //使用Postman或其他什么来做POST请求
  91. //使用RAW BODY的http//localhost:8080/user
  92. /*
  93. {
  94. "fname": "",
  95. "lname": "",
  96. "age": 45,
  97. "email": "mail@example.com",
  98. "favColor": "#000",
  99. "addresses": [{
  100. "street": "Eavesdown Docks",
  101. "planet": "Persphone",
  102. "phone": "none",
  103. "city": "Unknown"
  104. }]
  105. }
  106. */
  107. //Content-Type to application/json(可选,如果选择更好)。
  108. //由于空的`User.FirstName`(json中的fname),此请求将失败
  109. //和`User.LastName`(json中的lname)。
  110. //检查iris应用程序终端输出
  111. app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
  112. }
  113. // UserStructLevelValidation包含并非总是的自定义结构级别验证
  114. //在字段验证级别有同样有意义。例如,此函数验证了这一点
  115. //存在FirstName或LastName; 可以通过自定义字段验证完成,但随后
  116. //必须将它添加到复制逻辑+开销的两个字段中,这样就可以了,仅验证一次。
  117. //
  118. //注意:您可能会问为什么我不能在验证器之外执行此操作,因为这样做
  119. //挂钩到验证器,你可以与验证标签结合,但仍然有常见错误输出格式。
  120. func UserStructLevelValidation(sl validator.StructLevel) {
  121. user := sl.Current().Interface().(User)
  122. if len(user.FirstName) == 0 && len(user.LastName) == 0 {
  123. sl.ReportError(user.FirstName, "FirstName", "fname", "fnameorlname", "")
  124. sl.ReportError(user.LastName, "LastName", "lname", "fnameorlname", "")
  125. }
  126. //加上可以更多,甚至使用不同于“fnameorlname”的标签。
  127. }