当前位置: 首页 > news >正文

Java转Go日记(五十九):参数验证

1. 结构体验证

用gin框架的数据验证,可以不用解析数据,减少if else,会简洁许多。

package mainimport ("fmt""time""github.com/gin-gonic/gin"
)//Person ..
type Person struct {//不能为空并且大于10Age      int       `form:"age" binding:"required,gt=10"`Name     string    `form:"name" binding:"required"`Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
}func main() {r := gin.Default()r.GET("/5lmh", func(c *gin.Context) {var person Personif err := c.ShouldBind(&person); err != nil {c.String(500, fmt.Sprint(err))return}c.String(200, fmt.Sprintf("%#v", person))})r.Run()
}

代码启动之后,示例访问地址:

http://localhost:8080/5lmh?age=11&name=枯藤&birthday=2006-01-02

2. 自定义验证

package mainimport ("net/http""reflect""github.com/gin-gonic/gin""github.com/gin-gonic/gin/binding""gopkg.in/go-playground/validator.v8"
)/*对绑定解析到结构体上的参数,自定义验证功能比如我们要对 name 字段做校验,要不能为空,并且不等于 admin ,类似这种需求,就无法 binding 现成的方法需要我们自己验证方法才能实现 官网示例(https://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Custom_Functions)这里需要下载引入下 gopkg.in/go-playground/validator.v8
*/
type Person struct {Age int `form:"age" binding:"required,gt=10"`// 2、在参数 binding 上使用自定义的校验方法函数注册时候的名称Name    string `form:"name" binding:"NotNullAndAdmin"`Address string `form:"address" binding:"required"`
}// 1、自定义的校验方法
func nameNotNullAndAdmin(v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {if value, ok := field.Interface().(string); ok {// 字段不能为空,并且不等于  5lmhreturn value != "" && !("5lmh" == value)}return true
}func main() {r := gin.Default()// 3、将我们自定义的校验方法注册到 validator中if v, ok := binding.Validator.Engine().(*validator.Validate); ok {// 这里的 key 和 fn 可以不一样最终在 struct 使用的是 keyv.RegisterValidation("NotNullAndAdmin", nameNotNullAndAdmin)}/*curl -X GET "http://127.0.0.1:8080/testing?name=&age=12&address=beijing"curl -X GET "http://127.0.0.1:8080/testing?name=lmh&age=12&address=beijing"curl -X GET "http://127.0.0.1:8080/testing?name=adz&age=12&address=beijing"*/r.GET("/5lmh", func(c *gin.Context) {var person Personif e := c.ShouldBind(&person); e == nil {c.String(http.StatusOK, "%v", person)} else {c.String(http.StatusOK, "person bind err:%v", e.Error())}})r.Run()
}

示例2:

package mainimport ("net/http""reflect""time""github.com/gin-gonic/gin""github.com/gin-gonic/gin/binding""gopkg.in/go-playground/validator.v8"
)// Booking contains binded and validated data.
type Booking struct {//定义一个预约的时间大于今天的时间CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`//gtfield=CheckIn退出的时间大于预约的时间CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`
}func bookableDate(v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
) bool {//field.Interface().(time.Time)获取参数值并且转换为时间格式if date, ok := field.Interface().(time.Time); ok {today := time.Now()if today.Unix() > date.Unix() {return false}}return true
}func main() {route := gin.Default()//注册验证if v, ok := binding.Validator.Engine().(*validator.Validate); ok {//绑定第一个参数是验证的函数第二个参数是自定义的验证函数v.RegisterValidation("bookabledate", bookableDate)}route.GET("/5lmh", getBookable)route.Run()
}func getBookable(c *gin.Context) {var b Bookingif err := c.ShouldBindWith(&b, binding.Query); err == nil {c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})} else {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})}
}// curl -X GET "http://localhost:8080/5lmh?check_in=2019-11-07&check_out=2019-11-20"
// curl -X GET "http://localhost:8080/5lmh?check_in=2019-09-07&check_out=2019-11-20"
// curl -X GET "http://localhost:8080/5lmh?check_in=2019-11-07&check_out=2019-11-01"

 

3. 多语言翻译验证

当业务系统对验证信息有特殊需求时,例如:返回信息需要自定义,手机端返回的信息需要是中文而pc端发挥返回的信息需要时英文,如何做到请求一个接口满足上述三种情况。

package mainimport ("fmt""github.com/gin-gonic/gin""github.com/go-playground/locales/en""github.com/go-playground/locales/zh""github.com/go-playground/locales/zh_Hant_TW"ut "github.com/go-playground/universal-translator""gopkg.in/go-playground/validator.v9"en_translations "gopkg.in/go-playground/validator.v9/translations/en"zh_translations "gopkg.in/go-playground/validator.v9/translations/zh"zh_tw_translations "gopkg.in/go-playground/validator.v9/translations/zh_tw"
)var (Uni      *ut.UniversalTranslatorValidate *validator.Validate
)type User struct {Username string `form:"user_name" validate:"required"`Tagline  string `form:"tag_line" validate:"required,lt=10"`Tagline2 string `form:"tag_line2" validate:"required,gt=1"`
}func main() {en := en.New()zh := zh.New()zh_tw := zh_Hant_TW.New()Uni = ut.New(en, zh, zh_tw)Validate = validator.New()route := gin.Default()route.GET("/5lmh", startPage)route.POST("/5lmh", startPage)route.Run(":8080")
}func startPage(c *gin.Context) {//这部分应放到中间件中locale := c.DefaultQuery("locale", "zh")trans, _ := Uni.GetTranslator(locale)switch locale {case "zh":zh_translations.RegisterDefaultTranslations(Validate, trans)breakcase "en":en_translations.RegisterDefaultTranslations(Validate, trans)breakcase "zh_tw":zh_tw_translations.RegisterDefaultTranslations(Validate, trans)breakdefault:zh_translations.RegisterDefaultTranslations(Validate, trans)break}//自定义错误内容Validate.RegisterTranslation("required", trans, func(ut ut.Translator) error {return ut.Add("required", "{0} must have a value!", true) // see universal-translator for details}, func(ut ut.Translator, fe validator.FieldError) string {t, _ := ut.T("required", fe.Field())return t})//这块应该放到公共验证方法中user := User{}c.ShouldBind(&user)fmt.Println(user)err := Validate.Struct(user)if err != nil {errs := err.(validator.ValidationErrors)sliceErrs := []string{}for _, e := range errs {sliceErrs = append(sliceErrs, e.Translate(trans))}c.String(200, fmt.Sprintf("%#v", sliceErrs))}c.String(200, fmt.Sprintf("%#v", "user"))
}

正确的链接:http://localhost:8080/testing?user_name=枯藤&tag_line=9&tag_line2=33&locale=zh

http://localhost:8080/testing?user_name=枯藤&tag_line=9&tag_line2=3&locale=en 返回英文的验证信息

http://localhost:8080/testing?user_name=枯藤&tag_line=9&tag_line2=3&locale=zh 返回中文的验证信息

查看更多的功能可以查看官网 gopkg.in/go-playground/validator.v9

相关文章:

  • 自建 Derp 中继节点
  • Apache Doris + MCP:Agent 时代的实时数据分析底座
  • Java-39 深入浅出 Spring - AOP切面增强 核心概念 通知类型 XML+注解方式 附代码
  • 【Go语言基础【四】】局部变量、全局变量、形式参数
  • IDEA 开发PHP配置调试插件XDebug
  • 论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
  • 解锁FastAPI与MongoDB聚合管道的性能奥秘
  • 面试总结。
  • 《C++初阶之类和对象》【命名空间 + 输入输出 + 缺省参数 + 函数重载】
  • Sentinel微服务保护
  • MATLAB仿真:偏振光在光纤通信中的应用研究_可复现,有问题请联系博主
  • 【设计模式】门面/外观模式
  • Java 高频面试题场景(四):社区老年大学在线学习平台系统
  • 【Go语言基础【2】】数据类型之基础数据类型:数字、字符、布尔、枚举、自定义
  • 【Rust宏编程】Rust有关宏编程底层原理解析与应用实战
  • Monorepo架构: Lerna、NX、Turbo等对比与应用分析
  • 【Flask】:轻量级Python Web框架详解
  • Python----目标检测(yolov5-7.0安装及训练细胞)
  • 8086寻址解剖图:7种武器解锁x86内存访问的基因密码
  • AirSim/Cosys-AirSim 游戏开发(二)使用自定义场景
  • 教育类网站怎么做/除了91还有什么关键词
  • 网站抄袭别人的做可以吗/衡阳seo排名
  • seo怎么做网站的tdk/公司域名注册步骤
  • 上海建设工程交易中心网站/百度竞价推广登录
  • 信息安全网站建设方案书/拼多多搜索关键词排名
  • wordpress导航图标代码/android优化大师