GOLANG Web請求參數(shù)驗(yàn)證

基于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示例:
image.png

以上屬于原創(chuàng)文章胡诗,轉(zhuǎn)載請注明作者@怪咖
QQ:208275451

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市煌恢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌震庭,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件器联,死亡現(xiàn)場離奇詭異二汛,居然都是意外死亡婿崭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門肴颊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來氓栈,“玉大人,你說我怎么就攤上這事婿着∈谑荩” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵竟宋,是天一觀的道長提完。 經(jīng)常有香客問我,道長丘侠,這世上最難降的妖魔是什么氯葬? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮婉陷,結(jié)果婚禮上帚称,老公的妹妹穿的比我還像新娘。我一直安慰自己秽澳,他們只是感情好闯睹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著担神,像睡著了一般楼吃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妄讯,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天孩锡,我揣著相機(jī)與錄音,去河邊找鬼亥贸。 笑死躬窜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的炕置。 我是一名探鬼主播荣挨,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼朴摊!你這毒婦竟也來了默垄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤甚纲,失蹤者是張志新(化名)和其女友劉穎口锭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體介杆,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹃操,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年况既,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片组民。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡棒仍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出臭胜,到底是詐尸還是另有隱情,我是刑警寧澤耸三,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布仪壮,位于F島的核電站,受9級特大地震影響积锅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜适篙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一嚷节、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧硫痰,春花似錦窜护、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽敬矩。三九已至,卻和暖如春弧岳,著一層夾襖步出監(jiān)牢的瞬間业踏,已是汗流浹背涧卵。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工柳恐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乐设。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓近尚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親戈锻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,969評論 3 119
  • 2018叹卷、3月28、星期三骤竹、天氣晴、親子日記第二十五篇 今天下午下班回到家蒙揣,看到璐璐在認(rèn)真的寫作業(yè)开瞭,我心里很高興。...
    歐冠琪琪閱讀 203評論 0 0
  • 文/香丁 帶過孩子的人大概都有這樣的體會: 孩子小時候超級可愛个扰,越長大越不“聽話”葱色。因?yàn)楹⒆硬弧奥犜挕保改负秃⒆?..
    香丁閱讀 555評論 2 1
  • 距離我的26歲還不到一個月俐填,忽然意識到我已足夠胖,上樓喘氣赫段,腰上已不只一個游泳圈,大腿粗的似大象毫不夸張 大概在人...
    子魚的研究僧修行閱讀 177評論 1 0
  • 一直喜歡閱讀糯笙,以前閱讀沒有刻意選擇撩银,后來有了改變,開始選擇性的讀書够庙。 閱讀有精讀和粗讀,可以通過多種方式閱讀耘眨。有所...
    阿碩的蘋果閱讀 425評論 0 0