Gin框架简介 | 青训营笔记

154 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记

初识 Gin

创建一个go mod项目

安装

go get -u github.com/gin-gonic/gin

返回值类型

  • 可以使用map返回 key是string,v是interface{}
  • Gin框架给我们封装好了一个叫 gin.H,其实就是一个map
  • 也可以使用结构体来返回
    • 结构体属性名必须大写开头
    • 返回值就是以大写开头的属性名了,如果前端要求必须返回小写字母,那么就使用tag标签来给结构体做定制化操作

获取GET请求参数

url:localhost:9000/web?name=zhangsan

c.Query

获取POST请求参数

c.PostForm

注意:这里面的传参解析不是raw里的JSON

如果只是传单个的值要这么传入!!!!

如果传入的是JSON类型的数据,必须shouldBuild一下!!!!

获取路径参数

url:localhost:9000/web/1、localhost:9000/web/2

这和获取GET请求参数类似,使用Param()函数来获取,区别就是在路径上用 “:表示”,在java中用{}表示

	r.GET("/web/:num", func(c *gin.Context) {

		// 请求参数
		num := c.Param("num")
		data := gin.H{
			"msg":  "success",
			"data": num,
		}
		c.JSON(http.StatusOK, data)
	})

参数绑定

就是前端传过来的参数正好是结构体里面的属性,也就是我们常说的VO层吧。

**怎么样把前端传过来的参数匹配到结构体里面呢?
**在SpringBoot中使用的是@RequestBody注解实现的。

在Gin中,使用c.ShouldBind() 函数来完成

ShouldBind()函数底层利用的反射将数据保存到结构体中。

但是结构体有规定:

1、属性必须大写

2、要有tag标签,因为前端可能传过来的值可能和属性对不上

路由

  • get、post、delete、put等方法
  • 也有一个any方法,类似SpringBoot的@RequestMapping
  • 没有路由的页面-----NoRoute() 可以用作404错误处理页请求

路由组

就类似于SpringBoot在类上添加一个@RequestMapping 注解,使得业务分类.

路由组也支持嵌套

xxx :=r.Group("/home")
xxx.GET()
xxx.GET()

中间件

类似SpringAOP,那些公共方法抽取出来。

中间件的定义

其实我们写的r.GET() 函数,就使用了中间件

func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodGet, relativePath, handlers)
}

HandlerFunc,这个类型的函数就是中间件,所以中间件就是一个函数,参数类型是*gin.Context的就可以。

func m1(c *gin.Context)  {
	fmt.Println("m1....in")
	c.Next() // 调用后序处理的函数,有点递归的意思 这里相当于一个切入
    // c.About()   阻止调用后面的处理函数
	// 调用完之后可以执行下面的逻辑
	fmt.Println("m1....out")
}

// 一般写成闭包
func authMiddleware(doCheck bool) gin.Context {
	// 一些其他操作
	return func(c *gin.Context) {
		// 判断是否登录
		// if 登录了
		// c.Next()
		// else
		// c.About()
	}
}

这m1和authMiddleware****就是一个中间件

中间件的注册

两种方法:

  • 在每个Handler的第二个参数上添加,因为第二个参数是一个 ...类型,也就是可以多参数的形式(不推荐,比较麻烦)
  • 使用r.Use()全局注册
  • 可以配置多个,然后在中间件的里面可以控制执行顺序。
	r := gin.Default()
	r.Use(m1)

路由组注册

使用路由组注册,可以实现部分拦截功能(也就是说这个功能需要一部分方法去使用,那么就使用路由组注册)

为路由组注册中间件有以下两种写法:

// 方法一
shopGroup := r.Group("/shop", StatCost())
{
    shopGroup.GET("/index", func(c *gin.Context) {...})
    ...
}

// 方法二
shopGroup := r.Group("/shop")
shopGroup.Use(StatCost())
{
    shopGroup.GET("/index", func(c *gin.Context) {...})
    ...
}

上下文

类似于java中的ThreadLocal。就是说在中间件里面添加上一个信息,然后在其他函数中使用

// 一般写成闭包
func authMiddleware(doCheck bool) gin.Context {
	// 一些其他操作
	return func(c *gin.Context) {
        c.Set("mhy")    // 可以通过c.Set在请求上下文中设置值,后续的处理函数能够取到该值
		// 判断是否登录
		// if 登录了
		// c.Next()
		// else
		// c.About()
	}
}

func aaa(c *gin.Context) {
        uName,ok := c.Get("name")
        
		// 请求参数
		name := c.Query("name")
		data := gin.H{
			"msg":  "success",
			"data": name,
		}
		c.JSON(http.StatusOK, data)
	}