编写GO的WEB开发框架|编写GO的WEB开发框架 (六): Validator数据校验

2019独角兽企业重金招聘Python工程师标准>>> 编写GO的WEB开发框架|编写GO的WEB开发框架 (六): Validator数据校验
文章图片

一般地,获取到请求参数后,都需要根椐接口定义,对参数有一些合法性检查,比如:

  • 是否必填
  • 是否数字,数字的范围
  • 字符串的长度
  • 值是否在指定的列表中
  • 是否有效的日期
  • 是否满足指定的正式表达式
本篇讲述怎么编写一个Validator来对请求参数进行合法性检查。
validator的使用方法
设计一个功能时,我都习惯“目标驱动”,那就先来看看我期望的Validator怎么使用
func (this *Controller) User(){ validator:=NewValidator(this.Post) //将要检查的数据字典传入,生成Validator对象 validator.AddRule("name","string","2-5",true) //对字段name添加规则: 2-5个字符长度,必填 validator.AddRule("sport","list","football,swim",false) //对字段sport添加规则: 值需在列表中(football,swim),非必填 ... if err:= validator.Check(); err !=nil{ //检查不通过,处理错误 } }

相关结构、接口及实现
有了目标,就开始定义对象、接口及相关的方法
type Validator struct { data map[string]string //要校验的数据字典 rule map[string]*vRule //规则列表,key为字段名 } type vRule struct { vrValidateRuler required bool } //校验规则接口,支持自定义规则 type ValidateRuler interface { Check(data string) error } //内置规则结构,实现ValidateRuler接口 type normalRule struct { keystring rulestring params string } //创建校验器对象 func NewValidator(data map[string]string) *Validator { v := &Validator{data: data} v.rule = make(map[string]*vRule) return v }//添加内置的校验规则(同一个key只能有一条规则,重复添加会覆盖) func (this *Validator) AddRule(key string, rule string, params string, required ...bool) { nr := &normalRule{key, rule, params} this.rule[key] = &vRule{nr, true} //默认required = true if len(required) > 0 { this.rule[key].required = required[0] } }//框架不可能包括所有的规则,为了满足不同应用的需要,除了内置规则外,需同时支持自定义规则的添加。 //go不支持重载,所以定义一个新方法来添加自定义规则(使用ValidateRuler interface参数) func (this *Validator) AddExtRule(key string, rule ValidateRuler, required ...bool) { this.rule[key] = &vRule{rule, true} if len(required) > 0 { this.rule[key].required = required[0] } }

执行检查
//执行检查 func (this *Validator) Check() (errs map[string]error) { errs = make(map[string]error) for k, v := range this.rule { data, exists := this.data[k] if !exists { //无值 if v.required { //如果必填,报错 errs[k] = errors.New("data error: required field miss") } } else { //有值判断规则 if err := v.vr.Check(data); err != nil { //调用ValidateRuler接口的Check方法来检查 errs[k] = err } } } return errs }

内置规则实现ValidateRuler接口
接下来,编写normalRule的Check方法,以实现ValidateRuler接口
func (this *normalRule) Check(data string) (Err error) { if this.params == "" { Err = errors.New("rule error: params wrong of rule") return } switch this.rule { case "string": //字符串,根椐params判断长度的最大值和最小值 case "number": //判断是否整数数字 //判断最大值和最小值是否在params指定的范围 case "list": //判断值是否在params指定的列表 case "regular": //是否符合正则表达式 default: Err = errors.New(fmt.Sprintf("rule error: not support of rule=%s", this.rule)) } return }

使用自定义规则
当内置规则不满足时,开发者可以自定义规则来检查,只需规则实现了ValidateRuler 接口即可
type myRuler struct{ } //添加Check方法,实现ValidateRuler 接口 func (this *myRuler) Check(data string)(Err error){ //判断data是否符合规则 } //添加规则 validator.AddExtRule("name", &myRuler{})

【编写GO的WEB开发框架|编写GO的WEB开发框架 (六): Validator数据校验】转载于:https://my.oschina.net/tim8670/blog/632005

    推荐阅读