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示例:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值