原创作者,公众号【程序员读书】,欢迎关注公众号,转载文章请注明出处哦。
middleware
什么是Gin中间件
Gin中间件是什么?Gin中间件的作用是什么?要怎么样使用中间件呢?
1. Gin中间件的作用
好吧,简单来说,Gin中间件的作用有两个:
前置拦截器前置过滤器后置拦截器后置过滤器
2. Gin中间件的定义
在Gin框架中,中间件的类型定义如下代码所示,可以看出,中间件实际上就是一个以gin.Context为形参的函数而已,与我们定义处理HTTP请求的Handler本质上是一样的,并没有什么神秘可言。
type HandlerFunc func(*Context)
3. Gin内置中间件
在使用Gin框架开发Web应用时,常常需要自定义中间件,不过,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包装成中间件
中间的使用
1. 不使用默认中间件
gin.Default()gin.EngineRecoveryLoggergin.Default()
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())//使用Recovery和Logger中间
return engine
}
当我们不想使用这两个中间件时,可以使用gin.New()方法返回一个不带中间件的gin.Engine对象:
router := gin.New()//不带中间件
2. 全局使用中间件
gin.EngineUse()
router := gin.New()
router.Use(gin.Recovery())//在全局使用内置中间件
3. 路由分组使用中间件
路由分组(RouterGroup )
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) {
})
}
4. 单个路由使用中间件
除了路由分组,单个请求路由,也可以应用中间件,如下:
router := gin.New()
router.GET("/test",gin.Recovery(),func(c *gin.Context){
c.JSON(200,"test")
})
也可以在单个路由中使用多个中间件,如下:
router := gin.New()
router.GET("/test",gin.Recovery(),gin.Logger(),func(c *gin.Context){
c.JSON(200,"test")
})
自定义中间件
上面的讲解中,我们看到,虽然Gin提供了一些中间件,我们直接使用即可,但内置中间件可能满足不我们业务开发的需求,在开发过程中我们需要开自己的中间件,这在Gin框架中是非常简单的一件事。
HandlerFunc
type HandlerFunc func(*Context)
HandlerFunc规范了Gin中间件的定义,所以自定义中间件,如下:
//定义中间件
func MyMiddleware(c *gin.Context){
//中间件逻辑
}
定义好中间件,便可使用中间件,这里演示的是全局使用,也可以在单个路由或路由分组中使用:
router = gin.Default()
router.Use(MyMiddleware)
或者,通过自定义方法,返回一个中间件函数,这是Gin框架中更常用的方式:
//定义一个返回中间件的方法
func MyMiddleware(){
//自定义逻辑
//返回中间件
return func(c *gin.Context){
//中间件逻辑
}
}
使用自定义的中间件,注意MyMiddleware方法后面有加括号:
router = gin.Default()
router.Use(MyMiddleware())
数据传递
gin.ContextSet()Set()
func (c *Context) Set(key string, value interface{})
当我们在中间件中通过Set方法设置一些数值,在下一层中间件或HTTP请求处理方法中,可以使用下面列出的方法通过key获取对应数据。
interface{}
func (c *Context) Get(key string) (value interface{}, exists bool)
当我们确定通过Set方法设置对应数据类型的值时,可以使用下面方法获取应数据类型的值。
func (c *Context) GetBool(key string) (b bool)
func (c *Context) GetDuration(key string) (d time.Duration)
func (c *Context) GetFloat64(key string) (f64 float64)
func (c *Context) GetInt(key string) (i int)
func (c *Context) GetInt64(key string) (i64 int64)
func (c *Context) GetString(key string) (s string)
func (c *Context) GetStringMap(key string) (sm map[string]interface{})
func (c *Context) GetStringMapString(key string) (sms map[string]string)
func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string)
func (c *Context) GetStringSlice(key string) (ss []string)
func (c *Context) GetTime(key string) (t time.Time)
示例代码:
//自定义中间件
func MyMiddleware(c *gin.Context){
c.Set("mykey",10)
}
router := gin.New()
router.GET("test",MyMiddleware,func(c *gin.Context){
c.GetInt("mykey")//我们知道设置进行的是整型,所以使用GetInt方法来获取
})
拦截请求与后置拦截
1. 拦截请求
gin.Context
下面三个方法中断请求后,直接返回200,但响应的body中不会有数据。
func (c *Context) Abort()
func (c *Context) AbortWithError(code int, err error) *Error
func (c *Context) AbortWithStatus(code int)
使用AbortWithStatusJSON()方法,中断用户请求后,则可以返回json格式的数据.
func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{})
2. 后置拦截
gin.ContextNext()Next()
func (c *Context) Next()
Next()Next()Next()
func MyMiddleware(c *gin.Context){
//请求前
c.Next()
//请求后
}
示例代码
func MyMiddleware(c *gin.Context){
c.Set("key",1000)//请求前
c.Next()
c.JSON(http.StatusOK,c.GetInt("key"))//请求后
}
router := gin.New()
router.GET("test", MyMiddleware, func(c *gin.Context) {
k := c.GetInt("key")
c.Set("key", k+2000)
})
router.Run()
上面示例程序运行结果为3000,通过上面这样一个简单的示例程序,我们可以看到中间件在请求拦截请求,处理数据并控制Web请求流程的作用。
小结
middleware
你的关注,是我写作路上最大的鼓励!