3.4 KiB
3.4 KiB
一 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()
//请求后
}