GOLANG Web请求参数验证

基于golang web项目实际开发中在controller层对客户端请求参数进行验证,这样导致controller层代码冗余度非常高,影响开发效率。代码示例:

    feedback := &mysql_model.OfbankFeedback{}
    err := json.Unmarshal(body, feedback)
    feedback.FStatus=1
    feedback.CreateTime=time.Now()
    if err != nil {
        resp := apiservice.GenerateResponse(0, "请求参数有误", "")
        rw.Write([]byte(resp))
        return
    }
    if feedback.Phone=="" {
        resp := apiservice.GenerateResponse(0, "参数phone不能为空", "")
        rw.Write([]byte(resp))
        return
    }
    if feedback.Contacts=="" {
        resp := apiservice.GenerateResponse(0, "参数contacts不能为空", "")
        rw.Write([]byte(resp))
        return
    }
    if feedback.FType==0 {
        resp := apiservice.GenerateResponse(0, "参数fType不能为空", "")
        rw.Write([]byte(resp))
        return
    }
    if feedback.Img==""&&feedback.Content=="" {
        resp := apiservice.GenerateResponse(0, "参数img或content不能同时为空", "")
        rw.Write([]byte(resp))
        return
    }

代码冗余度高?影响开发效率?如何解决?

目前有很多web框架(beego、faygo等)支持结构体参数验证;为了解决项目管理上的问题引入一个框架且框架中参数验证规则扩展性不是很好,个人感觉不是很优雅;于是自己写了一个结构体参数验证工具(struct_util.go)

代码示例:
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzhao
 * Date: 2018-07-17
 * Time: 11:08
 */
package utils

import (
    "reflect"
    "errors"
    "strings"
    "strconv"
)
//自定义验证规则
const (
    NOT_EMPTY = "NotEmpty" //字符串不能为空
    INT_MAX = "int-max" //int最大值
    INT_MIN = "int-min" //int最小值
    TYPE = "type" //类型
    STR_MAX_LENGTH = "str-max-len" //字符串最大长度
    STR_MIN_LENGTH = "str-min-len" //字符串最小长度
    STR_LENGTH = "str-len" //字符串长度
    RANGE = "range" //元素必须在合适的范围内 例:1-100
)
//对外暴露结构体验证函数
func StructValidate(bean interface{}) error {
    fields := reflect.ValueOf(bean).Elem()
    for i := 0; i < fields.NumField(); i++ {
        field := fields.Type().Field(i)
        valid := field.Tag.Get("valid")
        if valid == "" {
            continue
        }
        value := fields.FieldByName(field.Name)
        err := fieldValidate(field.Name, valid, value)
        if err != nil {
            return err
        }
    }
    return nil
}
//属性验证
func fieldValidate(fieldName, valid string, value reflect.Value) error {
    valids := strings.Split(valid, " ")
    for _, valid := range valids {

        if strings.Index(valid, TYPE) != -1 {
            v := value.Type().Name()
            split := strings.Split(valid, "=")
            t := split[1]
            if v != t {
                return errors.New(fieldName + " type must is " + t)
            }
        }

        if strings.Index(valid, NOT_EMPTY) != -1 {
            str := value.String()
            if str == "" {
                return errors.New(fieldName + " value not empty")
            }
        }
        if strings.Index(valid, INT_MIN) != -1 {
            v := value.Int()
            split := strings.Split(valid, "=")
            rule, err := strconv.Atoi(split[1])
            if err != nil {
                return errors.New(fieldName + ":验证规则有误")
            }
            if int(v) < rule {
                return errors.New(fieldName + " value must >= " + strconv.Itoa(rule))
            }
        }

        if strings.Index(valid, INT_MAX) != -1 {
            v := value.Int()
            split := strings.Split(valid, "=")
            rule, err := strconv.Atoi(split[1])
            if err != nil {
                return errors.New(fieldName + ":验证规则有误")
            }
            if int(v) > rule {

                return errors.New(fieldName + " value must <= " + strconv.Itoa(rule))
            }
        }
        //字符串特殊处理
        if value.Type().Name() == "string" {
            if strings.Index(valid, STR_LENGTH) != -1 {
                v := value.String()
                split := strings.Split(valid, "=")
                lenStr := split[1]
                length, err := strconv.Atoi(lenStr)
                if err != nil {
                    return errors.New(fieldName + " " + STR_LENGTH + " rule is error")
                }
                if len(v) != length {
                    return errors.New(fieldName + " str length  must be " + lenStr)
                }
            }
            if strings.Index(valid, STR_MAX_LENGTH) != -1 {
                v := value.String()
                split := strings.Split(valid, "=")
                lenStr := split[1]
                length, err := strconv.Atoi(lenStr)
                if err != nil {
                    return errors.New(fieldName + " " + STR_LENGTH + " rule is error")
                }
                if len(v) > length {
                    return errors.New(fieldName + " str length  <= " + lenStr)
                }
            }

            if strings.Index(valid, STR_MIN_LENGTH) != -1 {
                v := value.String()
                split := strings.Split(valid, "=")
                lenStr := split[1]
                length, err := strconv.Atoi(lenStr)
                if err != nil {
                    return errors.New(fieldName + " " + STR_LENGTH + " rule is error")
                }
                if len(v) < length {
                    return errors.New(fieldName + " str length  >= " + lenStr)
                }
            }
        }
    }
    return nil
}
demo示例:
image.png

以上属于原创文章,转载请注明作者@怪咖
QQ:208275451

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,050评论 3 119
  • 2018、3月28、星期三、天气晴、亲子日记第二十五篇 今天下午下班回到家,看到璐璐在认真的写作业,我心里很高兴。...
    欧冠琪琪阅读 1,365评论 0 0
  • 文/香丁 带过孩子的人大概都有这样的体会: 孩子小时候超级可爱,越长大越不“听话”。因为孩子不“听话”,父母和孩子...
    香丁阅读 3,674评论 2 1
  • 距离我的26岁还不到一个月,忽然意识到我已足够胖,上楼喘气,腰上已不只一个游泳圈,大腿粗的似大象毫不夸张 大概在人...
    子鱼的研究僧修行阅读 1,248评论 1 0
  • 一直喜欢阅读,以前阅读没有刻意选择,后来有了改变,开始选择性的读书。 阅读有精读和粗读,可以通过多种方式阅读。有所...
    阿硕的苹果阅读 3,106评论 0 0