当前位置:   article > 正文

Go实战Gin+Vue+微服务打造秒杀商城第二课 模板语法和路由组_golang中gt=10的用法

golang中gt=10的用法

GO模板语法

模板语法一

源代码路径:chapter03\test_syntax_tpl.go

模板路径:template\chapter03\test.html

一、统一使用了 { { 和 } } 作为左右标签,

二、上下文

  • . 访问当前位置的上下文
  • $ 引用当前模板根级的上下文
  • $. 引用模板中的根级上下文

三、支持go语言的符号,这里只是符号的支持

1.字符串:{ { “zhiliao ” } }

2.原始字符串:{ { zhiliao } } 不会转义

3.字节类型:{ { ’ a’ } } -->97 ascll码对应表: http://ascii.911cha.com/

4.nil类型:{ { print nil } } { {nil } }只有nil会报错:nil is not a command

四、定义变量

1.定义:

{{$username := "xxxx"}}
  • 1

2.使用:

{{$username }}
  • 1

注意:只能在当前模板中使用

五、pipline

1.可以是上下文的变量输出,也可以是函数通过管道传递的返回值

e.g.

  • { {.Name} } 是上下文的变量输出,是个pipline
  • { { “hallen” | len } } 是函数通过管道传递的返回值,是个pipline

六、if

1.if…else

{{if .name}}
    有姓名
{{else}}
    没有姓名
{{end}}
  • 1
  • 2
  • 3
  • 4
  • 5

2.if嵌套

成年人而且带了身份证的准进:
{{if .A}}
    {{if .C }}
        可以进
    {{else}}
        不能进
    {{end}}
{{else}}
    未成年不能进
{{end}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

七、range

第一种:
{{range $v := .arr_struct}}
    {{$v.Name}}
    {{$v.Age}}
    {{$v.Gender}}
{{end}}

下面的也可以
{{range $v := .arr}}
    {{/*{{$v}}*/}}
    {{.}}
{{end}}

第二种:
{{ range .arr_struct }}
    {{.Name }}
    {{.Age}}
    {{ $.total}} // 使用 $. 引用模板中的根级上下文
{{end}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

range也支持else,当长度为0时,执行else

{{range .total}}
    {{.}}
{{else}}
    {{ 0 }}                 {{/* 当 .total 为空 或者 长度为 0 时会执行这里 */}}
{{end}}
  • 1
  • 2
  • 3
  • 4
  • 5

模板语法二

一、with:伴随

1.作用:用于重定向 pipeline

2.使用

{{with .user}}
    {{.Id}}
    {{.Name}}
{{end}}
  • 1
  • 2
  • 3
  • 4

不用每个字段前面都加user.了

3.支持else,当长度为0时,显示else中的数据

{{with .user}}
    {{.Id}}
    {{.Name}}
{{else}}
    暂无数据
{{end}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

场景:登录的用户显示用户名,没有登录的用户显示"游客"

二、template

1.作用:引入另一个模板文件,对于模板的分模块处理很有用处,

2.使用:{ {template “模板名” pipeline} }

e.g.

{{template "user/test.html" .}}
  • 1

注意:

  • 引入的模板文件中也要用{ {define “user/test.html”} } { {end} }包含
  • 如果想在引入的模板中也需要获取动态数据,必须使用.访问当前位置的上下文

三、注释

允许多行文本注释,不允许嵌套

{{/* comment content
support new line */}}


{{/*
这是模板块注释
这是模板块注释
这是模板块注释
这是模板块注释
*/}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

模板函数

源代码路径:chapter03\test_func_tpl.go

模板路径:template\chapter03\terst_func_tpl.html

一、print

print:对应 fmt.Sprint
printf:对应 fmt.Sprintf

println:对应 fmt.Sprintln

{{print "hallen"}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
格式化输出:
  • %c:字符型,可以把输入的数字按照ASCII码相应转换为对应的字符
  • %d:一个十进制数值,基数为10
  • %f:以标准计数法表示的浮点数或者复数值
  • %s:字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0’结尾,这个’\0’即空字符)
  • %t:以true或者false输出的布尔值
  • %T:查看类型
  • %v:自动匹配类型输出,适用于大多数类型

fmt.Sprint和fmt.Print的区别:

  • Print有打印,Sprint没有打印,但是可以返回结果

二、管道符

变量可以使用符号 | 在函数间传递

{{.Name | printf "%s"}}
  • 1

三、括号 优先级

{{printf "nums is %s %d" (printf "%d %d" 1 2) 3}}

{{printf "name:%s,addr:%s" "hallen" (printf "%s-%s" "北京市" "西城区")}}
  • 1
  • 2
  • 3

四、and

1.作用:只要有一个为空,则整体为空,如果都不为空,则返回最后一个

2.使用:

{{and .X .Y .Z}}
  • 1

五、or

1.作用:只要有一个不为空,则返回第一个不为空的,否则返回空

2.使用:

{{or .X .Y .Z}}
  • 1

六、call(看自定义模板函数)

1.作用:可以调用函数,并传入参数

2.使用:

{{call .Field .Arg1 .Arg2}}
  • 1

七、index

1.作用:读取指定类型对应下标的值

2.支持 map, slice, array, string

e.g.

数据准备:
arr := []int{1,2,3,4,5}
message := map[string]interface{}{
    "arr":arr,
    "name":map[string]interface{}{"name":"xx111","age":18},
}


使用:
{{index .name "name"}}
{{index .arr 1}}

注意:数组的角标从0开始的
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

八、len

1.作用:返回对应类型的长度

2.支持类型:map, slice, array, string, chan

e.g.

{{.arr | len}}
  • 1

九、not

1.作用:返回输入参数的否定值

2.使用

{{not .arr1}}
  • 1

十、urlquery

1.作用:有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了。

2.使用

{{urlquery "http://www.baidu.com"}}

结果:http%3A%2F%2Fwww.baidu.com

% 后面的就是字符的16进制的字符码
  • 1
  • 2
  • 3
  • 4
  • 5

十一、eq / ne / lt / le / gt / ge

1.eq:等于

2.ne:不等于

3.lt:小于 less

4.le:小于等于

5.gt:大于 greater

6.ge:大于等于

{{eq .num 18}}

{{ne .num 17}}

{{lt .num 16}}

{{le .num 18}}

{{gt .num 18}}

{{ge .num 18}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

eq 和其他函数不一样的地方是,支持多个参数

{{eq .num 10 11 17 18}}
  • 1

模板函数二

一、Format

1.实现了时间的格式化,返回字符串,也可以在后端转好,前端直接使用

2.使用方法

  • 使用方法 { {.time_data.Format “2006/01/02 15:04:05”} }

  • 设置时间格式比较特殊,需要按如下方式,一定不能变

    • “2006/01/02 15:04:05”
    • 貌似是GO的诞生的时间
  • 和go语言的使用方法类似

  • now := time.Now().Format("2006/01/02 15:04:05")
    
    • 1

二、html

1.作用:转义文本中的html标签

如将“<”转义为“<”,“>”转义为“>”等

三、js

1.作用:返回用JavaScript的escape处理后的文本

escape函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串

可以使用unescape解吗

{{js "<script>xx</script>"}}

结果:\x3Cscript\x3Exx\x3C/script\x3E
  • 1
  • 2
  • 3

模板函数整理

var builtins = FuncMap{
"and":      and,
"call":     call,
"html":     HTMLEscaper,
"index":    index,
"js":       JSEscaper,
"len":      length,
"not":      not,
"or":       or,
"print":    fmt.Sprint,
"printf":   fmt.Sprintf,
"println":  fmt.Sprintln,
"urlquery": URLQueryEscaper,


// Comparisons
"eq": eq, // ==
"ge": ge, // >=
"gt": gt, // >
"le": le, // <=
"lt": lt, // <
"ne": ne, // !=
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

自定义模板函数

一、定义函数

func SubStr(str string,l int) string {

    ret := str[0:l]
    return (ret + "...")
}
  • 1
  • 2
  • 3
  • 4
  • 5

二、SetFuncMap

engine.SetFuncMap(template.FuncMap{
        "SubStr": SubStr,      // 字符串名称是前端使用的名称
    })
  • 1
  • 2
  • 3

三、前端使用

{{SubStr "qwertyuu" 3}}
  • 1

注意:是左闭右开区间

gin数据绑定及验证

数据绑定介绍

Gin提供了两类绑定方法:

  • Type
    • Must bind
      • Methods -Bind,BindJSON,BindXML,BindQuery,BindYAML
      • Behavior
        • 这些方法属于MustBindWith的具体调用。 如果发生绑定错误,则请求终止,并触发 c.AbortWithError(400, err).SetType(ErrorTypeBind) 。响应状态码被设置为 400 并且Content-Type被设置为text/plain; charset=utf-8 。 如果您在此之后尝试设置响应状态码,Gin会输出日志[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422 。 如果您希望更好地控制绑定,考虑使用ShouldBind等效方法。
  • Type
    • Should bind
      • Methods -ShouldBind,ShouldBindJSON,ShouldBindXML,ShouldBindQuery,ShouldBindYAML
      • Behavior
        • 这些方法属于ShouldBindWith的具体调用。 如果发生绑定错误,Gin 会返回错误并由开发者处理错误和请求。

数据绑定–Should bind

一、ShouldBind

可以绑定Form、QueryString、Json,uri

form标签:Form、QueryString

json标签:Json

uri标签:uri

form的绑定示例代码:

// 结构体
type User struct {
    Id int `form:"id" json:"id"`               
    Name string `form:"name" json:"name"`

}

// 注意:structTag:指定字段名称,不用使用首字母大写的


// 绑定
var user User
context.ShouldBind(&user)
fmt.Println(user)



// 前端
<form action="/dobind" method="post">
    <input type="text" name="name"><br>
    <input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

QueryString的绑定示例代码:

// 结构体中structTag的form起作用



var user User
context.ShouldBind(&user)
fmt.Println(user)


访问:http://127.0.0.1:8080/tobind?name=zhiliao&age=110
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

json的绑定示例代码

// 结构体中structTag的json起作用



func DoBind(context *gin.Context)  {

    var user User
    context.ShouldBind(&user)

    fmt.Println(user)

    context.JSON(200,gin.H{
        "msg":"success",
        "code":200,
    })

}

前端:ajax

<form>
    <input type="text" name="name" id="name"><br>
    <input type="text" name="age" id="age"><br>
    <input type="button" value="提交" id="btn_add">
</form>

<script>
    var btn_add = document.getElementById("btn_add");
    btn_add.onclick = function (ev) {
        var name = document.getElementById("name").value;
        var age = document.getElementById("age").value;

        $.ajax({
            url:"/dobind",
            type:"POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data:JSON.stringify({
                "name":name,
                "age":Number(age)
            }),
            success:function (data) {
                console.log(data);
            },
            fail:function (data) {
                console.log(data);
            }
        })



    }
</script>

注意:
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    "age":Number(age)    age是个int类型,必须得转成int类型才可以直接绑定
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

二、ShouldBindWith

可以使用显式绑定声明绑定 multipart form:

c.ShouldBindWith(&form, binding.Form)

或者简单地使用 ShouldBind 方法自动绑定

三、ShouldBindQuery等

ShouldBindJSON,ShouldBindXML,ShouldBindQuery,ShouldBindYAML等函数只绑定对应格式的参数

四、ShouldBindUri:绑定 Uri

使用structTag:uri

// 结构体中structTag的uri起作用


结构体:
type User struct {
    Id int `uri:"id"`
    Name string `uri:"name"`
    Age int `uri:"age"`

}

路由:engine.GET("/tobind2/:name/:age",ToBind)


func ToBind(context *gin.Context)  {
    var user User
    context.ShouldBindUri(&user)
    fmt.Println(user)

    context.String(200,"success")

}


访问:http://127.0.0.1:8080/tobind2/zhiliao/110
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

数据绑定–Must bind

一、Bind

可以绑定Form、QueryString、Json等

和ShouldBind的区别在于,ShouldBind没有绑定成功不报错,就是空值,Bind会报错

二、BindQuery等

BindJSON,BindXML,BindQuery,BindYAML等函数只绑定对应格式的参数

数据验证

go-playground/validator.v8进行验证

一、使用

使用structTag的binding,如:binding:“required”

如果没有空值或者类型不匹配就会报错,重定向到400 (Bad Request)

错误信息:Key: ‘User.Name’ Error:Field validation for ‘Name’ failed on the ‘required’ tag

示例代码:

type User struct {
    Id int `form:"id"`
    Name string `form:"name" binding:"required"`   // 不为空校验
    Age int `form:"age"`

}



func DoBind(context *gin.Context)  {

    var user User
    err := context.ShouldBind(&user)
    if err != nil {
        fmt.Println(err)
        context.JSON(400,gin.H{
            "msg":"fali",
            "code":400,
        })
    }

    context.JSON(200,gin.H{
        "msg":"success",
        "code":200,
    })

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

二、其他验证器

注意:

  • 多个验证器之间用英文输入法下的逗号(,)隔开,并且是按照验证器的顺序执行的

  • 如果希望在参数中包含逗号(即excludesall =,),则需要使用UTF-8十六进制表示形式0x2C

    • e.g.

      validate:"excludesall=0x2C"

1.- 忽略字段,如:binding:“-”

2.required: 必填字段,如:binding:“required”

3.min 最小长度,如:binding:“min=10”

4.max 最大长度,如:binding:“max=10”

5.| 或,如:binding:“rgb|rgba”

6.structonly 如果有嵌套,可以决定只验证结构体上的,binding:“structonly”

7.Exists

8.omitempty 省略空,如果为空,则不会继续验证该字段上其他的规则,只有不为空才会继续验证其他的,如max等

9.dive 嵌套验证

1.name [][]string  `binding:"gt=0,dive,len=1,dive,required"`

// gt = 0将应用于[]
// len = 1将应用于[] string
//必填项将应用于字符串



2.name [][]string  `binding:"gt=0,dive,dive,required"`

// gt = 0 将应用于[]
// []string 将保留验证
//必填项将应用于字符串
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

10.len 长度,如:binding:“len=10”

11.eq 等于,如:binding:“eq=10”

12.ne 不等于,如:binding:“ne=10”

13.gt 大于,如:binding:“gt=10”

14.gte 大于等于,如:binding:“gte=10”

15.lt 小于,如:binding:“lt=10”

16.lte 小于等于,如:binding:“lte=10”

注意:gt、gte、lt、lte等都可以用于时间的比较,后面不需要跟值,直接binding:“gt”,表示大于当前utc时间

17.eqfield 等于其他字段的值,如:Password string binding:"eqfield=ConfirmPassword"

18.nefield 不等于其他字段的值,

19.eqcsfield 类似eqfield,它会验证相对于顶层结构提供的字段,

如:eqcsfield = InnerStructField.Field)
  • 1

20.necsfield

21.gtfield 大于其他字段的值

22.gtefield

23.gtcsfield

24.gtecsfield

25.ltfield 小于其他字段的值

26.ltefield

27.ltcsfield

28.ltecsfield

29.alpha 字符串值仅包含字母字符

30.alphanum 字符串值仅包含字母数字字符

31.numeric 字符串值包含基本数字值。基本不包括指数等…

32.hexadecimal 字符串值包含有效的十六进制

33.hexcolor 验证字符串值包含有效的十六进制颜色,包括井号(#)

34.rgb 字符串值包含有效的rgb颜色

35.rgba 字符串值包含有效的rgba颜色

36.HSL 字符串值包含有效的hsl颜色

37.hsla 字符串值包含有效的hsla颜色

38.email 字符串值包含有效的电子邮件

39.url 字符串值包含有效的网址,必须包含http://等

40.uri 字符串值包含有效的uri。它将接受golang请求uri接受的任何uri

41.base64 字符串值包含有效的base64值

42.contains 字符串值包含子字符串值,contains=@

43.containsany 包含所有,containsany =!@#?

44.containsrune 字符串值包含提供的符号 containsrune = @

45.excludes 字符串值不包含子字符串值,excludes = @

46.excludeall 排除所有

47.excluderune 字符串值不包含提供的符号,excluderune = @

48.isbn 国际标准书号,验证字符串值包含有效的isbn10或isbn13值。

49.isbn10 国际标准书号10, 验证字符串值包含有效的isbn10值。

50.isbn13 国际标准书号13,字符串值包含有效的isbn13值。

51.uuid 字符串值包含有效的UUID。

52.uuid3 字符串值包含有效的版本3 UUID

53.uuid4 字符串值包含有效的版本5 UUID。

54.uuid5 字符串值包含有效的版本5 UUID。

55.ascii 字符串值仅包含ASCII字符。注意:如果字符串为空,则验证为true。

56.asciiprint 字符串值仅包含可打印的ASCII字符。注意:如果字符串为空,则验证为true。

57.multibyte 字符串值包含一个或多个多字节字符。注意:如果字符串为空,则验证为true。

58.datauri 字符串值包含有效的DataURI。注意:这还将验证数据部分是有效的base64

59.latitude 纬度,字符串值包含有效的纬度

60.longitude 经度,字符串值包含有效的经度。

61.ssn 字符串值包含有效的美国社会安全号码

62.ip 字符串值包含有效的IP地址

63.ipv4 字符串值包含有效的v4 IP地址。

64.ipv6 字符串值包含有效的v6 IP地址。

65.cidr 字符串值包含有效的CIDR地址。

66.cidrv4 字符串值包含有效的CIDR地址。

67.cidrv6 字符串值包含有效的v6 CIDR地址。

68.tcp_addr 字符串值包含有效的可解析TCP地址。

max,len,min:

  • 对于数字,max将确保该值等于给定的参数。
  • 对于字符串,它将检查字符串长度是否恰好等于该字符数。
  • 对于切片,数组和地图,验证项目数

官方文档:

https://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags

自定义验证器

https://gin-gonic.com/zh-cn/docs/examples/custom-validators/

一、安装包

go get github.com/go-playground/validator

二、使用

1.定义验证器

var Len6Valid validator.Func = func(fl validator.FieldLevel) bool {
    data := fl.Field().Interface().(string)
    if len(data) > 6 {
        fmt.Println("false")
        return false
    }else {
        fmt.Println("true")
        return true
    }
}


注意:必须为validator.Func类型
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2.注册验证器

if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
        v.RegisterValidation("len_valid", valid.Len6Valid)
    }

在路由匹配前,main中即可
  • 1
  • 2
  • 3
  • 4
  • 5

3.结构体中使用

type Article struct {
    Id int `form:"id"`
    Title string `form:"title" binding:"required,len_valid"`
    Desc string `form:"desc" binding:"required,len_valid"`
}

这里必须binding中,而且名称为前面注册的字符串名称
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

beego中的验证器

用于数据校验:
  • 校验数据是否合法
安装
go get github.com/astaxie/beego/validation
  • 1
验证方法:
  • Required 不为空,即各个类型要求不为其零值
  • Min(min int) 最小值,有效类型:int,其他类型都将不能通过验证
  • Max(max int) 最大值,有效类型:int,其他类型都将不能通过验证
  • Range(min, max int) 数值的范围,有效类型:int,他类型都将不能通过验证
  • MinSize(min int) 最小长度,有效类型:string slice,其他类型都将不能通过验证
  • MaxSize(max int) 最大长度,有效类型:string slice,其他类型都将不能通过验证
  • Length(length int) 指定长度,有效类型:string slice,其他类型都将不能通过验证
  • Alpha alpha字符,有效类型:string,其他类型都将不能通过验证
  • Numeric 数字,有效类型:string,其他类型都将不能通过验证
  • AlphaNumeric alpha 字符或数字,有效类型:string,其他类型都将不能通过验证
  • Match(pattern string) 正则匹配,有效类型:string,其他类型都将被转成字符串再匹配(fmt.Sprintf(“%v”, obj).Match)
  • AlphaDash alpha 字符或数字或横杠 -_,有效类型:string,其他类型都将不能通过验证
  • Email 邮箱格式,有效类型:string,其他类型都将不能通过验证
  • IP IP 格式,目前只支持 IPv4 格式验证,有效类型:string,其他类型都将不能通过验证
  • Base64 base64 编码,有效类型:string,其他类型都将不能通过验证
  • Mobile 手机号,有效类型:string,其他类型都将不能通过验证
  • Tel 固定电话号,有效类型:string,其他类型都将不能通过验证
  • Phone 手机号或固定电话号,有效类型:string,其他类型都将不能通过验证
  • ZipCode 邮政编码,有效类型:string,其他类型都将不能通过验证
通过 StructTag校验数据:
  • 验证函数写在 “valid” tag 的标签里
  • 各个验证规则之间用分号 “;” 分隔,分号后面可以有空格
  • 参数用括号 “()” 括起来,多个参数之间用逗号 “,” 分开,逗号后面可以有空格
  • 正则函数(Match)的匹配模式用两斜杠 “/” 括起来
  • 各个函数的结果的 key 值为字段名.验证函数名
type LoginParams struct {
      Name string valid:"Required"
      Age int    valid:"Required;MinSize(2)"
      Addr string    valid:"Required"
 }

func (l *LoginController) Post()  {
        valid := validation.Validation{}
     // 解析到结构体
      params := LoginParams{}
      if err := l.ParseForm(&params); err != nil {
          //handle error
          return
      }

      //重写错误信息:validation.SetDefaultMessage(map)
      var messages = map[string]string{
        "Required": "不能为空",
        "MinSize":  "最短长度为 %d",
        "Length":   "长度必须为 %d",
        "Numeric":  "必须是有效的数字",
        "Email":    "必须是有效的电子邮件地址",
        "Mobile":   "必须是有效的手机号码",
      }
      validation.SetDefaultMessage(messages)

      // 校验
      b, err := valid.Valid(&params)

      // 验证StructTag 是否正确
      if err != nil {

          fmt.Println(err)
      }

      if !b {   
          // 验证没通过,则b为false
          for _, err := range valid.Errors {
              fmt.Println(err.Key, err.Message)
              message := err.Key + err.Message
              l.Ctx.WriteString(message)
          }
      }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
多个StructTag之间用空格隔开

gin路由组

路由组介绍

https://gin-gonic.com/zh-cn/docs/examples/grouping-routes/

一、路由组的作用

  1. 区分版本
  2. 区分模块

二、使用

v1 := engine.Group("/v1")
v2 := engine.Group("/v2")


{
    v1.GET("/tobind", ToBind)
    v1.GET("/hello3", Hello3)
}

{
    v2.GET("/my_valid", valid.MyValid)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

路由抽取

一、抽取规则

  1. 总路由中设置路由组
  2. 模块中的路由负责映射具体的业务

二、示例

1.main.go中

"gin_test_project/routers"

router := gin.Default()

routers.Routers(router)   // routers是总路由的package名称
  • 1
  • 2
  • 3
  • 4
  • 5

2.总路由

package routers

import (
    "github.com/gin-gonic/gin"
    "gin_test_project/valid"
)

func Routers(router *gin.Engine)  {

    valid_router := router.Group("/v1")
    valid.Routers(valid_router)   // valid是项目中的valid模块package名称

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3.模块路由

package valid

import (
    "github.com/gin-gonic/gin"
)

func Routers(valid_router *gin.RouterGroup)  {

    {
        valid_router.GET("/my_valid", MyValid)
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/457410
推荐阅读
相关标签
  

闽ICP备14008679号