当前位置:首页 » 《关注互联网》 » 正文

go-zero结合自定义模版校验前端参数

13 人参与  2024年09月26日 17:20  分类 : 《关注互联网》  评论

点击全文阅读


一、自定义模版的使用

如果想对官网goctl命名生成的项目结构改变的话,可以使用模版,自定义模版,然后生成自己想要的文件

1、使用命令将官方模版映射到本地

goctl template init

2、在项目的根目录下添加文件夹,把刚刚映射到本地的拷贝到项目中

在这里插入图片描述

3、使用模版根据api文件来生成go的文件

# 注意这个地方要根据你当前路径来找到goctl文件夹goctl api go -api *api --dir . --style=goZero --home ../../goctl

4、注意

goctl api go -api *.api -dir . --style=gozero可以根据api文件来生成项目,也是修改了api来更新项目goctl api new user是创建一个userapi项目

二、使用go-playground对前端数据校验

1、安装依赖包

go get -u github.com/go-playground/validator/v10

2、在translator.go文件中自定义将错误翻译成中文

package utilsimport ("errors""github.com/go-playground/locales/zh"ut "github.com/go-playground/universal-translator""github.com/go-playground/validator/v10"zhTranslations "github.com/go-playground/validator/v10/translations/zh""go_zero_demo05/common/utils/validators""reflect""strings")func Validate(dataStruct interface{}) error {zhT := zh.New()validate := validator.New()// 注册一个函数,获取struct tag里自定义的label作为字段名validate.RegisterTagNameFunc(func(fld reflect.StructField) string {name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]if name == "-" {return ""}return name})uni := ut.New(zhT)trans, _ := uni.GetTranslator("zh")// 注册自定义结构体字段校验方法// 1.注册时间要比当前的晚if err := validate.RegisterValidation("checkAfterDate", validators.ValidateAfterDate); err != nil {return err}if err := validate.RegisterTranslation("checkAfterDate",trans,registerTranslator("checkAfterDate", "{0} 必须要晚于当前日期"),translate,); err != nil {return err}// 验证器注册翻译器if err := zhTranslations.RegisterDefaultTranslations(validate, trans); err != nil {return err}err := validate.Struct(dataStruct)if err != nil {for _, err1 := range err.(validator.ValidationErrors) {return errors.New(err1.Translate(trans))}}return nil}// registerTranslator 为自定义字段添加翻译功能func registerTranslator(tag string, msg string) validator.RegisterTranslationsFunc {return func(trans ut.Translator) error {if err := trans.Add(tag, msg, false); err != nil {return err}return nil}}// translate 自定义字段的翻译方法func translate(trans ut.Translator, fe validator.FieldError) string {msg, err := trans.T(fe.Tag(), fe.Field())if err != nil {panic(fe.(error).Error())}return msg}

3、关于自定义校验方法

package validatorsimport ("github.com/go-playground/validator/v10""time")// ValidateAfterDate 判断时间是否是当前时间之后func ValidateAfterDate(fl validator.FieldLevel) bool {date, err := time.Parse("2006-01-02", fl.Field().String())if err != nil {return false}if date.Before(time.Now()) {return false}return true}

4、自定义模版handler.tpl中添加前端参数校验的方法

package {{.PkgName}}import ("net/http""github.com/zeromicro/go-zero/rest/httpx"{{.ImportPackages}})func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {{{if .HasRequest}}var req types.{{.RequestType}}if err := httpx.Parse(r, &req); err != nil {httpx.ErrorCtx(r.Context(), w, err)            return}// 数据验证        if validateErr := utils.Validate(&req);validateErr != nil {            httpx.ErrorCtx(r.Context(), w, validateErr)            return        }{{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx){{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}&req{{end}})if err != nil {            httpx.ErrorCtx(r.Context(), w, err)        } else {            {{if .HasResp}}httpx.OkJsonCtx(r.Context(), w, resp){{else}}httpx.Ok(w){{end}}        }}}

5、在定义api的时候加上参数校验

type PostDemoReq {Name string `json:"name" validate:"required"` // 姓名Age  int64  `json:"age" validate:"required,gte=1,lte=130"` // 年龄// optional 表示可选,omitempty如果为空的时候不走后面Mobile         string `json:"mobile,optional" validate:"omitempty,checkMobile"` // 手机号码Email          string `json:"email,optional" validate:"omitempty,checkEmail"` // 邮箱地址Date           string `json:"date" validate:"omitempty,checkDate,checkAfterDate"` // 时间Password       string `json:"password" validate:"required"` // 密码ConfimPassword string `json:"confimPassword" validate:"eqfield=Password"` // 确认密码}

optional表示go-zero参数是可选,一个很大作用是生成的swagger上没有标识必填字段

checkMobilecheckEmailcheckAfterDate都是自定义校验器,需要在translator.go注册才能使用

omitempty表示如果为空的话,就不走后面的校验

在这里插入图片描述

6、使用命令用模版生成文件,注意导包的问题

goctl api go -api *api --dir . --style=goZero --home ../../goctl

7、自测错误,并且返回给前端

在这里插入图片描述

8、当go-zero中标识必填字段的时候提示的错误为下面,比如name字段不写的时候,age字段数据类型错误的时候
在这里插入图片描述

9、age数据类型错误的时候

在这里插入图片描述

三、翻译go-zero中的参数错误

1、自定义translatorError.go翻译文件

package utilsimport ("fmt""regexp""strings")func TranslatorError(err error) string {reg := regexp.MustCompile(`"(.*)?"`)match := reg.FindString(err.Error())if strings.Contains(err.Error(), "is not set") {if match != "" {return fmt.Sprintf("%s 为必填字段!", strings.Replace(match, `"`, "", -1))}} else if strings.Contains(err.Error(), "mismatch for field") {if match != "" {return fmt.Sprintf("%s 数据类型不对!", strings.Replace(match, `"`, "", -1))}}return ""}

2、在返回错误拦截器中添加使用

func ErrHandler(name string) func(ctx context.Context, err error) (int, any) {return func(ctx context.Context, err error) (int, any) {fmt.Println(err, "错误信息")causeErr := errors.Cause(err)fmt.Println(causeErr, "111-->")var errMessage = err.Error()// 翻译错误translatorError := TranslatorError(err)if translatorError != "" {errMessage = translatorError}// 日志记录logx.WithContext(ctx).Errorf("【%s】 err %v", name, errMessage)return http.StatusBadRequest, Fail(errMessage)}}

3、当年龄数据类型错误的时候

在这里插入图片描述

4、name字段没写的时候
在这里插入图片描述

5、另外name为空字符串的时候

在这里插入图片描述

四、参考文档

1、go-playground文档

2、go-zero官网


点击全文阅读


本文链接:http://zhangshiyu.com/post/164999.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1