Go中使用govalidator校验URL参数无法自动填充对应结构体的问题
根因说明
thedevsaddam/govalidator的Validate()方法默认仅执行参数规则校验,不会自动将URL查询参数填充到传入的结构体实例,只有针对请求体的ValidateJSON()、ValidateForm()方法默认开启了结构体自动填充逻辑。
解决方案
两种可选实现都无需手动调用r.URL.Query().Get()逐个取值:
方案1:直接获取校验完成的参数集合
校验无错误后调用库内置的GetValidData()方法,直接返回所有通过校验的参数map:
func ValidateItemRequest(r *http.Request, w http.ResponseWriter) map[string]interface{} { var itemRequest ItemsRequest rules := govalidator.MapData{ "item": []string{"numeric"}, } opts := govalidator.Options{ Request: r, Rules: rules, Data: &itemRequest, RequiredDefault: true, } v := govalidator.New(opts) e := v.Validate() if len(e) > 0 { // 自定义错误处理逻辑 return e } // 直接取已经校验完成的参数集合,无需再读请求原参数 validData := v.GetValidData() itemValue := validData["item"] // 后续业务逻辑 return nil }
方案2:开启自动注入,直接填充结构体
修改结构体添加valid标签匹配URL参数名,同时在初始化校验配置时开启参数自动注入开关,校验完成后结构体就会被自动填充:
- 修改结构体定义:
type ItemsRequest struct { // valid标签的值需要和URL查询参数名完全一致 Item string `json:"item" valid:"item"` }
- 调整校验配置:
func ValidateItemRequest(r *http.Request, w http.ResponseWriter) map[string]interface{} { var itemRequest ItemsRequest rules := govalidator.MapData{ "item": []string{"numeric"}, } opts := govalidator.Options{ Request: r, Rules: rules, Data: &itemRequest, RequiredDefault: true, // 开启校验通过后自动将参数值注入到结构体的开关 InjectTagValueToAutoType: true, } v := govalidator.New(opts) e := v.Validate() if len(e) > 0 { // 自定义错误处理逻辑 return e } // 直接访问结构体字段即可,已经被自动填充 itemValue := itemRequest.Item // 后续业务逻辑 return nil }
内容的提问来源于stack exchange,提问作者Nicole Staline
相关产品推荐
相关产品推荐

