1. 自定义验证

都在代码里自己看吧

  1. package main
  2. import (
  3. "net/http"
  4. "reflect"
  5. "github.com/gin-gonic/gin"
  6. "github.com/gin-gonic/gin/binding"
  7. "gopkg.in/go-playground/validator.v8"
  8. )
  9. /*
  10. 对绑定解析到结构体上的参数,自定义验证功能
  11. 比如我们要对 name 字段做校验,要不能为空,并且不等于 admin ,类似这种需求,就无法 binding 现成的方法
  12. 需要我们自己验证方法才能实现 官网示例(https://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Custom_Functions)
  13. 这里需要下载引入下 gopkg.in/go-playground/validator.v8
  14. */
  15. type Person struct {
  16. Age int `form:"age" binding:"required,gt=10"`
  17. // 2、在参数 binding 上使用自定义的校验方法函数注册时候的名称
  18. Name string `form:"name" binding:"NotNullAndAdmin"`
  19. Address string `form:"address" binding:"required"`
  20. }
  21. // 1、自定义的校验方法
  22. func nameNotNullAndAdmin(v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
  23. if value, ok := field.Interface().(string); ok {
  24. // 字段不能为空,并且不等于 admin
  25. return value != "" && !("5lmh" == value)
  26. }
  27. return true
  28. }
  29. func main() {
  30. r := gin.Default()
  31. // 3、将我们自定义的校验方法注册到 validator中
  32. if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
  33. // 这里的 key 和 fn 可以不一样最终在 struct 使用的是 key
  34. v.RegisterValidation("NotNullAndAdmin", nameNotNullAndAdmin)
  35. }
  36. /*
  37. curl -X GET "http://127.0.0.1:8080/testing?name=&age=12&address=beijing"
  38. curl -X GET "http://127.0.0.1:8080/testing?name=lmh&age=12&address=beijing"
  39. curl -X GET "http://127.0.0.1:8080/testing?name=adz&age=12&address=beijing"
  40. */
  41. r.GET("/5lmh", func(c *gin.Context) {
  42. var person Person
  43. if e := c.ShouldBind(&person); e == nil {
  44. c.String(http.StatusOK, "%v", person)
  45. } else {
  46. c.String(http.StatusOK, "person bind err:%v", e.Error())
  47. }
  48. })
  49. r.Run()
  50. }

示例2:

  1. package main
  2. import (
  3. "net/http"
  4. "reflect"
  5. "time"
  6. "github.com/gin-gonic/gin"
  7. "github.com/gin-gonic/gin/binding"
  8. "gopkg.in/go-playground/validator.v8"
  9. )
  10. // Booking contains binded and validated data.
  11. type Booking struct {
  12. //定义一个预约的时间大于今天的时间
  13. CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
  14. //gtfield=CheckIn退出的时间大于预约的时间
  15. CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`
  16. }
  17. func bookableDate(
  18. v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
  19. field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
  20. ) bool {
  21. //field.Interface().(time.Time)获取参数值并且转换为时间格式
  22. if date, ok := field.Interface().(time.Time); ok {
  23. today := time.Now()
  24. if today.Unix() > date.Unix() {
  25. return false
  26. }
  27. }
  28. return true
  29. }
  30. func main() {
  31. route := gin.Default()
  32. //注册验证
  33. if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
  34. //绑定第一个参数是验证的函数第二个参数是自定义的验证函数
  35. v.RegisterValidation("bookabledate", bookableDate)
  36. }
  37. route.GET("/5lmh", getBookable)
  38. route.Run()
  39. }
  40. func getBookable(c *gin.Context) {
  41. var b Booking
  42. if err := c.ShouldBindWith(&b, binding.Query); err == nil {
  43. c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
  44. } else {
  45. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  46. }
  47. }
  48. // curl -X GET "http://localhost:8080/5lmh?check_in=2019-11-07&check_out=2019-11-20"
  49. // curl -X GET "http://localhost:8080/5lmh?check_in=2019-09-07&check_out=2019-11-20"
  50. // curl -X GET "http://localhost:8080/5lmh?check_in=2019-11-07&check_out=2019-11-01"