gin框架基础

目录

一、请求路由

1.多种请求类型

2.静态文件夹

3.参数作为URL

4.泛绑定:

二、获取请求参数

1.获取GET请求参数

2.获取POST请求参数

3.获取Body值

4.获取参数绑定结构体

三、验证请求参数

1.结构体验证

2.自定义验证

3.升级验证-支持多语言错误信息

四、中间件

1.使用gin中间件

(1)gin.Logger()中间件

 (2)Recovery()中间件

2.自定义ip白名单中间件

 五、基础拓展

1.优雅关停

2.模板渲染

3.自动证书配置


一、请求路由

1.多种请求类型

主要包括"get" "put" "post" "delete"等八种请求类型

r := gin.Default()
//GET(路由,回调方法)  回调方法返回的内容是一个字符串
r.GET("/get",func(c *gin.Context){
    c.String(200,"get")
})
//有个Any方法,可以设置多种请求类型打到相同的路由下面
//Any方法里面支持八种请求类型,基本上覆盖了http所有的请求方法
r.Any("/any",func(c *gin.Context){
    c.String(200,"any")
})

2.静态文件夹

可以把gin当作静态服务器来使用

/*
设置静态文件夹绑定:r.Static(路由,静态文件夹)
另外一种写法:r.StaticFS("/static"路由,http.Dir("static")资源)
设置单个静态文件: r.StaticFile(路由,资源)
*/
r.Static("/assets","./assets")
r.StaticFS("/static",http.Dir("static"))
r.StaticFile("/favicon.ico","./favicon.ico")

在对应位置设置静态文件夹。

 3.参数作为URL

gin框架基础_第1张图片

r.GET(...)方法创建一个Get路由,这里面设置一下获取name的url参数,再设置下获取id的url参数,再设置它的回调参数,返回的内容使用json。

返回值是200,返回内容是gin.H{}就是一个map结构

测试:

第一个参数是name,第二个参数是id。

结果和传入的参数值相同,输出格式是json

4.泛绑定:

所有前缀的请求都定向到一个资源中,类似nginx的前缀匹配

泛绑定和普通用法的区别在于前缀的匹配,所有的匹配都会打到相同的方法上。

gin框架基础_第2张图片

所有/user前缀的请求都会打到hello world上来。

二、获取请求参数

(补充:

post是通过HTTPpost机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。

对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。)

1.获取GET请求参数

r := gin.Default()
//r.GET(...)方法创建一个gin的路由,定义一个/test的路由
r.GET("/test",func(c *gin.Context){
/*
回调方法两个参数firstName, lastName.
firstName是一个不带默认值的参数,lastName获取默认数据,第一个是参数的名称,第二个是设置的默认值。*/
    firstName := c.Query("first_name")
    lastName := c.DefaultQuery("last_name","last_default_name")
    //c.String(...)以string的方式输出这个值
    c.String(http.StatusOK,"%s,%s",firstName,lastName)
})

2.获取POST请求参数

firstName := ctx.PostForm("first_name")
lastName := ctx.DefaultPostForm("last_name","default_last_name")

3.获取Body值

这里的body一般是指body row之类的数据流请求,可能是结构化的数据,也可能是port buffer之类的数据

//要拿到body的内容,要借助ioutil.ReadAll()方法,参数为默认的request里面的body数据流。返回一个字节数组和error
r.POST("/test", func(c *gin.Context){
    bodyBytes, err := ioutil.ReadAll(c.Request.Body)
    if err != nil{
        c.String(http.StatusBadRequest, err.Error())
        //c.Abort()直接让输出结束
        c.Abort()
    }
    c.String(http.StatusOK,string(bodyBytes))
})

4.获取参数绑定结构体

这是gin的核心功能

构想是想用post和get同时访问到一个相同的回调方法里,接收到的参数都是一个结构体

如果是post请求,根据post请求的参数值转化为这个结构体。

如果是get请求,根据get请求的参数值转化为这个结构体。

//定义结构体,有三项内容 后面加上tag`...` form意思是请求参数可以通过这个结构体进行转换,由参数转变为结构体。
type Person struct{
    Name string `form:"name"`
    Address string `form:"address"`
    Birthday time.Time `form:"birthday"`
}

func main(){
    r := gin.Default()
    r.GET("/testing",testing)
    r.POST("/testing",testing)
}

func testing(c *gin.Context){
    var person Person
    //开始对数据进行binding操作
    //使用ShouldBind()这个方法,接收interface类型参数,返回的值是err
    //实际上这一步不管get还是post,会根据请求类型的contentType动态解释相应的请求的数据的格式到这个结构体里面。如,get就直接可以识别 name = 某个值&address=某个值...
    //post就可以直接从formdata里面拿,如果我们请求的是json,就可以直接从json中解析出这个数据。
    //总之,ShouldBind()里面,能考虑到的格式都已经兼容了,前提是header里面必须要传content-type
    if err := c.ShouldBind(&person); err == nil{
        c.String(200,"%v",person)
    }else{
        c.String(200,"person bind error:%v",err)
    }
}

三、验证请求参数

1.结构体验证

一般将验证规则定义到结构体的tag上面进行验证

type Person struct{
    Age int `form:"age" binding:"required,gt=10"`
    Name string `form:"name" binding:"required"`
    Address string `form:"address" binding:"required"`
}

func main(){
    r := gin.Default()
    r.GET("/testing",func(c *gin.Context){
        var person Person
        if err := c.ShouldBind(&person);err != nil{
            c.String(500,"%v",err)
        }
        c.String(200,"%v",person)
    })
    r.Run()
}

gin框架基础_第3张图片

其他验证规则参考官方gopkg文档

gin默认封装的规则是基于这个validator.v8来使用的。

validator.v8官网

多个验证之间用逗号分隔

验证 例子
或的验证  |
存在的验证 exists
支持非空 omitempty

支持slice验证,并且slice可以是二维数组

dive

必传和字段长度的验证

required, len=10

最大最小值验证

max=10, min=10

等于和不等于某值的验证

eq=10, ne=10

大于某值,小于某值

gt=10, lt=10

小于等于某值

lte=10

字段比对相同值的验证

1.eqfiled=ConfirmPassword

2.validate.FieldWithValue(password,confirmpassword,"eqfield")

3.eqcsfield=InnerStructField.Field

一些字符串验证的例子:只包含字母、数字等

1.只包含字母:alpha

2.只包含字母和数字:alphanum

3.只包含数字:numeric

2.自定义验证

结构体验证不能满足要求时,需要自定义规则

3.升级验证-支持多语言错误信息

根据请求的语言进行错误信息转换

四、中间件

中间件是介于gin服务器和回调函数执行的一个中间层,它可以用来做请求拦截和日志打印

1.使用gin中间件

使用gin.Default()方法创建gin实例,gin.Default()里会默认实现两个中间件Logger()和Recovery()

(1)gin.Logger()中间件

作用是在请求的时候会在控制台打印一行请求地址的url和耗时等信息

gin框架基础_第4张图片

 会输出状态码200,执行的时间、ip、请求方法、路由

如果想把错误打印到文件,需要设置下gin.Logger()打印的位置

gin框架基础_第5张图片

gin.DefaultWriter = io.MuilWriter(f)把日志信息输出到f文件中

gin.DefaultErrorWriter = io.MuilWriter(f)把错误信息也输出到f文件中

控制台中不再输出,输出在gin.log文件中

gin框架基础_第6张图片

 (2)Recovery()中间件

gin框架基础_第7张图片

 当代码里面有一个panic,如果没有使用Recovery()中间件,这个GET请求会报错,以至于传到main里面会报错,这个服务就断掉了。但是使用了Recovery就会捕获掉这个错误,不至于导致进程去挂掉。

2.自定义ip白名单中间件

(1).首先创建文件夹middelware_whitelist和main.go文件

(2).创建gin实例

(3).定义一个对应的中间件,去use。在use之前,先把原来的请求路由设置一下。

(4).参考Logger()和recover()中间件的实现,返回HandlerFunc

定义白名单放到一个数组里ipList,实际上应该放到配置文件里面,每次用的时候再进行提取

(5).设置一个flag标签,默认为false

(6).遍历ip列表,它的比对对象是client的一个数据,client又是我们当前访问者的ip

gin框架基础_第8张图片

 gin框架基础_第9张图片

 五、基础拓展

1.优雅关停

是指服务器处理时如果未处理完毕,会有一个超时等待时间去完成后续的一个处理,保证服务不在中间中断停止

2.模板渲染

在前后端不分离之前的一个概念是比较火的。主要是说数据的后端,可以将数据与html混合到一起输出。

3.自动证书配置

是指无需配置任何证书,即可自动下载证书。过期之后还可以自动续约的证书的功能

你可能感兴趣的:(Go基础,golang)