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示例:
GOLANG Web请求参数验证_第1张图片
image.png

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

你可能感兴趣的:(GOLANG Web请求参数验证)