over-golang/05-常用框架/gin-04-中间件.md
2021-07-02 18:11:59 +08:00

3.4 KiB
Raw Permalink Blame History

一 Gin中间件

1.1 中间件的概念

gin框架允许在处理请求时加入用户自己的钩子函数该钩子函数即中间件。他的作用与Java中的拦截器Node中的中间件相似。

中间件需要返回gin.HandlerFunc函数多个中间件通过Next函数来依次执行。

1.2 入门使用案例

现在设计一个中间件,在每次路由函数执行前打印一句话,在上一节的项目基础上新建middleware文件夹,新建一个中间件文件MyFmt.go

package middleware

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

// 定义一个中间件
func MyFMT() gin.HandlerFunc {
	return func(c *gin.Context) {
		host := c.Request.Host
		fmt.Printf("Before: %s\n",host)
		c.Next()
		fmt.Println("Next: ...")
	}
}

在路由函数中使用中间件:

r.GET("/user/login", middleware.MyFMT(),  userLogin)

打印结果:

Before: localhost:8080
Next: ...
[GIN] 2019/07/28 - 16:28:16 | 200 |      266.33µs |             ::1 | GET      /user/login

1.2 中间件的详细使用方式

全局中间件:直接使用 gin.Engine结构体的Use()方法,中间件将会在项目的全局起作用。

func InitRouter() *gin.Engine {

	r := gin.Default()

	// 全局中间件
	r.Use(middleware.MyFMT())

	// 路由模块化
	userRouter(r)
	orderRouter(r)

	return r
}

路由分钟中使用中间件:

router := gin.New()
user := router.Group("user", gin.Logger(),gin.Recovery())
{
    user.GET("info", func(context *gin.Context) {

    })
    user.GET("article", func(context *gin.Context) {

    })
}

单个路由使用中间件(支持多个中间件的使用)

router := gin.New()
router.GET("/test",gin.Recovery(),gin.Logger(),func(c *gin.Context){
    c.JSON(200,"test")
})

1.3 内置中间件

Gin也内置了一些中间件可以直接使用

func BasicAuth(accounts Accounts) HandlerFunc
func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc
func Bind(val interface{}) HandlerFunc //拦截请求参数并进行绑定
func ErrorLogger() HandlerFunc       //错误日志处理
func ErrorLoggerT(typ ErrorType) HandlerFunc //自定义类型的错误日志处理
func Logger() HandlerFunc //日志记录
func LoggerWithConfig(conf LoggerConfig) HandlerFunc
func LoggerWithFormatter(f LogFormatter) HandlerFunc
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc
func Recovery() HandlerFunc
func RecoveryWithWriter(out io.Writer) HandlerFunc
func WrapF(f http.HandlerFunc) HandlerFunc //将http.HandlerFunc包装成中间件
func WrapH(h http.Handler) HandlerFunc //将http.Handler包装成中间件

二 请求的拦截与后置

中间件的最大作用就是拦截过滤请求,比如我们有些请求需要用户登录或者需要特定权限才能访问,这时候便可以中间件中做过滤拦截。

下面三个方法中断请求后直接返回200但响应的body中不会有数据

func (c *Context) Abort()
func (c *Context) AbortWithError(code int, err error) *Error
func (c *Context) AbortWithStatus(code int)
func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{})		// 中断后可以返回json数据

如果在中间件中调用gin.Context的Next()方法,则可以请求到达并完成业务处理后,再经过中间件后置拦截处理:

func MyMiddleware(c *gin.Context){
    //请求前
    c.Next()
    //请求后
}