gin框架入门(六)-中间件

目录

概述

使用和不使用默认中间件

自定义中间件

ctx.Next()、ctx.Abort()

中间件和控制器间传值

在中间件中使用goroutine

引用中间件

路由中使用中间件

路由组中使用中间件

全局使用中间件


概述

        中间件就是匹配路由前和匹配路由完成后执行的一系列操作。Gin框架允许开发者在处理请求的过程中,加入自己的钩子函数(Hook)。这个钩子函数就叫中间件。

        中间件适合处理一些公共的业务逻辑,比如登陆认证、权限校验、数据分页、记录日志、耗时统计。

使用和不使用默认中间件

在使用gin.Default()创建Gin引擎时,已经自带了Logger()、Recovery()中间件。

  • Logger中间件将日志写入gin.DefaultWriter。
  • Recovery中间件会recover任何panic。如果有panic的话,会写入500响应码。

如果创建Gin引擎时,不想使用默认的中间件。可以使用gin.New()。但是不建议这么做。

自定义中间件

目录结构

project

        |--main.go

        |--routers(目录)

                |--routerGroupInit.go

                |--userRouterGroup.go

        |--controllers(目录)

                |--user(目录)

                        |--userControllers.go

        |--middileware(目录)

                |--simpleMiddleware.go

定义中间件-simpleMiddleware.go

其实语法就和写控制器一样。

package mddileware

import (
	"fmt"

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

func SimpleMiddleware(c *gin.Context) {
	fmt.Println("SimpleMiddleware")
}

ctx.Next()、ctx.Abort()

1.ctx.Next()

调用请求的剩余处理程序,常用于计算程序执行时间。

package mddileware

import (
	"fmt"

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

func SimpleMiddleware(c *gin.Context) {
	fmt.Println("SimpleMiddleware")
	c.Next()
	fmt.Println("SimpleMiddleware--2")
}

此代码先执行打印“SimpleMiddleware”;然后到c.Next()时会向后调用路由中定义的其他控制器;等向后所有控制器都执行完后,再打印“SimpleMiddleware-2”。

2.ctx.Abort()

终止请求剩余的控制器。

package middleware

import (
	"fmt"

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

func SimpleMiddleware(c *gin.Context) {
	fmt.Println("SimpleMiddleware")
	c.Abort()
	fmt.Println("SimpleMiddleware--2")
}

此代码先执行打印“SimpleMiddleware”;然后到c.Abort()时不再调用后续的中间件和控制器;再打印“SimpleMiddleware-2”。

中间件和控制器间传值

//设置数据
ctx.Set("keyname", "value")

//获取数据
vname, _ := ctx.Get("keyname")

注意:这里获取到的vname是一个空接口类型(interface{})。使用类型断言转为其他类型,如:

v, _ := vname.(string)        转为字符串类型

在中间件中使用goroutine

当在中间件或者handler中使用goroutine时,不能直接使用原始的上下文(c *gin.Context)。必须使用c.Copy()创建其只读副本,使用只读副本。

package middleware

import (
	"fmt"
	"net/http"
	"time"

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

func SimpleMiddleware(c *gin.Context) {
	cCp := c.Copy()
	go func() {
		time.Sleep(time.Second * 2)
		fmt.Println("Path:" + cCp.Request.URL.Path)
	}()

	c.JSON(http.StatusOK, gin.H{
		"msg": "SimpleMiddleware-1",
	})
}

配置使用中间件

路由中使用中间件

路由方法中,我们是可以传入多个控制器的。如果传入多个自定义控制器,则最后一个控制器是实际处理业务逻辑,前面的控制器都是中间件。

package routers

import (
	"hello/controllers/user"
	"hello/middleware"

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

func UserRouterGroupInit(r *gin.Engine) {
	userGroup := r.Group("/user")
	{
		userGroup.GET("/userInfo", middleware.SimpleMiddleware, user.UserController{}.GetUserInfo)
		userGroup.POST("/userAdd", middleware.SimpleMiddleware, user.UserController{}.PostUserAdd)
	}
}

路由组中使用中间件

路由组配置中间件有两种方法

方法一:

r.Group("path", middleware, ...)

package routers

import (
	"hello/controllers/user"
	"hello/middleware"

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

func UserRouterGroupInit(r *gin.Engine) {
	userGroup := r.Group("/user", middleware.SimpleMiddleware)
	{
		userGroup.GET("/userInfo", user.UserController{}.GetUserInfo)
		userGroup.POST("/userAdd", user.UserController{}.PostUserAdd)
	}
}

方法二:

RouterGroup.Use(middleware, ...)

package routers

import (
	"hello/controllers/user"
	"hello/middleware"

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

func UserRouterGroupInit(r *gin.Engine) {
	userGroup := r.Group("/user")
	userGroup.Use(middleware.SimpleMiddleware)
	{
		userGroup.GET("/userInfo", user.UserController{}.GetUserInfo)
		userGroup.POST("/userAdd", user.UserController{}.PostUserAdd)
	}
}

全局使用中间件

route.Use()方法,定义全局中间件。同样可以使用逗号分隔,定义多个中间件。

package main

import (
	"hello/middleware"
	"hello/routers"

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

func main() {
	r := gin.Default()
	r.Use(middleware.SimpleMiddleware)
	routers.RouterGroupInit(r)
	r.Run(":8080")
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值