基于golang web項(xiàng)目實(shí)際開發(fā)中在controller層對客戶端請求參數(shù)進(jìn)行驗(yàn)證聪姿,這樣導(dǎo)致controller層代碼冗余度非常高梯浪,影響開發(fā)效率恕曲。代碼示例:
feedback := &mysql_model.OfbankFeedback{}
err := json.Unmarshal(body, feedback)
feedback.FStatus=1
feedback.CreateTime=time.Now()
if err != nil {
resp := apiservice.GenerateResponse(0, "請求參數(shù)有誤", "")
rw.Write([]byte(resp))
return
}
if feedback.Phone=="" {
resp := apiservice.GenerateResponse(0, "參數(shù)phone不能為空", "")
rw.Write([]byte(resp))
return
}
if feedback.Contacts=="" {
resp := apiservice.GenerateResponse(0, "參數(shù)contacts不能為空", "")
rw.Write([]byte(resp))
return
}
if feedback.FType==0 {
resp := apiservice.GenerateResponse(0, "參數(shù)fType不能為空", "")
rw.Write([]byte(resp))
return
}
if feedback.Img==""&&feedback.Content=="" {
resp := apiservice.GenerateResponse(0, "參數(shù)img或content不能同時為空", "")
rw.Write([]byte(resp))
return
}
代碼冗余度高褥影?影響開發(fā)效率离例?如何解決?
目前有很多web框架(beego宫蛆、faygo等)支持結(jié)構(gòu)體參數(shù)驗(yàn)證艘包;為了解決項(xiàng)目管理上的問題引入一個框架且框架中參數(shù)驗(yàn)證規(guī)則擴(kuò)展性不是很好洒扎,個人感覺不是很優(yōu)雅衰絮;于是自己寫了一個結(jié)構(gòu)體參數(shù)驗(yàn)證工具(struct_util.go)
代碼示例:
/**
* Created with IntelliJ IDEA.
* Description:
* User: yangzhao
* Date: 2018-07-17
* Time: 11:08
*/
package utils
import (
"reflect"
"errors"
"strings"
"strconv"
)
//自定義驗(yàn)證規(guī)則
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" //元素必須在合適的范圍內(nèi) 例:1-100
)
//對外暴露結(jié)構(gòu)體驗(yàn)證函數(shù)
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
}
//屬性驗(yàn)證
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 + ":驗(yàn)證規(guī)則有誤")
}
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 + ":驗(yàn)證規(guī)則有誤")
}
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示例:
以上屬于原創(chuàng)文章胡诗,轉(zhuǎn)載請注明作者@怪咖
QQ:208275451