基於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 utilsimport ( "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}
以上屬於原創文章,轉載請註明作者@怪咖
QQ:208275451