标签:SET Context 中间件 gin m1 func m2 GIN
-------------
1. C.NEXT()演示
//HandlerFunc
func indexHandler(c *gin.Context) {
fmt.Println("index")
c.JSON(http.StatusOK, gin.H{
"msg": "index",
})
}
//定义一个中间件
func m1(c *gin.Context) {
fmt.Println("m1 in ...")
// 计时
start := time.Now()
c.Next() //调用后续的处理函数
//c.Abort() //阻止调用后续的处理函数
cost := time.Since(start)
fmt.Printf("cost:%v\n", cost)
fmt.Printf("m1 out ...")
}
func m2(c *gin.Context) {
fmt.Println("m2 in ...")
c.Next() //调用后续的处理函数
fmt.Println("m2 out ...")
}
func main() {
r := gin.Default()
//点GET查看源码发现
//GET(relativePath string, handlers ...HandlerFunc) IRoutes 另外,...表示 可传多个HandlerFunc类型的函数
//r.GET("/index", m1, indexHandler)
//r.GET("/shop", m1, func(c *gin.Context) {
// c.JSON(http.StatusOK, gin.H{
// "msg": "shop",
// })
//})
//r.GET("/user", m1, func(c *gin.Context) {
// c.JSON(http.StatusOK, gin.H{
// "msg": "user",
// })
//})
// 点开Use 查看源码发现 Use(middleware ...HandlerFunc) IRoutes
r.Use(m1, m2) //全局注册中间件函数m1 m2
/*访问/index
执行indexHandler之前 去执行注册的中间件 总的执行打印顺序是:m1 in -> m2 in -> index -> m2 out -> m1 out
*/
r.GET("/index", indexHandler)
r.GET("/shop", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "shop",
})
})
r.GET("/user", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "user",
})
})
r.Run(":9090")
}
执行结果:
执行逻辑:
代码执行图解:
2. C.ABORT()演示:
上面代码把m2这里改成阻止,其他地方不变,如下图:
此时执行,控制台打印输出为:
m1 in -> m2 in ->m2 out -> m1 out
- 1
代码执行图解:
当然,如果连 m2 out 都不想让它输出的话,那直接在c.Abort() 语句 后return就可以了,如下图:
3. C.SET() C.GET 跨中间件取值
//HandlerFunc
func indexHandler(c *gin.Context) {
fmt.Println("index")
name, ok := c.Get("name") //取值 实现了跨中间件取值
if !ok{
name = "default user"
}
c.JSON(http.StatusOK, gin.H{
"msg": name,
})
}
//定义一个中间件
func m1(c *gin.Context) {
fmt.Println("m1 in ...")
// 计时
start := time.Now()
//gin中间件中使用goroutine
//当在中间件或handler中启动新的goroutine时,不能使用原始的上下文(c *gin.Context),必须使用其只读副本(c.Copy())
go otherFunc(c.Copy()) // 在otherFunc中只能使用c的拷贝
c.Next() //调用后续的处理函数
//c.Abort() //阻止调用后续的处理函数
cost := time.Since(start)
fmt.Printf("cost:%v\n", cost)
fmt.Printf("m1 out ...")
}
func m2(c *gin.Context) {
fmt.Println("m2 in ...")
c.Set("name", "tony") //可以在请求上下文里面设置一些值,然后其他地方取值
c.Abort() //阻止调用后续的处理函数 也就是 m2它自己走完就行
//return
fmt.Println("m2 out ...")
}
// 自定义认证中间件 通过这种方式实现一些灵活的控制
func authMiddleware(doCheck bool)gin.HandlerFunc {
//连接数据库
// 或其他一些准备工作
return func(c *gin.Context) {
if doCheck {
//这里存放具体的逻辑
// 是否登录的判断
// if 是登录用户
c.Next()
// else
// c.Abort()
}else {
c.Next()
}
}
}
func main() {
r := gin.Default()
// 点开Use 查看源码发现 Use(middleware ...HandlerFunc) IRoutes
r.Use(m1, m2, authMiddleware(true)) //全局注册中间件函数m1 m2 authMiddleware
/*访问/index
执行indexHandler之前 去执行注册的中间件 总的执行打印顺序是:m1 in -> m2 in -> index -> m2 out -> m1 out
*/
r.GET("/index", indexHandler)
r.GET("/shop", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "shop",
})
})
r.GET("/user", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "user",
})
})
/* 路由组注册中间件方法1
routeGroup1 := r.Group("/xx", authMiddleware(true)){
routeGroup1.GET("/index", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"msg": "routeGroup1"})
})
}
路由组注册中间件方法2
routeGroup2 := r.Group("/xx2")
routeGroup2.Use(authMiddleware(true)){
routeGroup2.GET("/index", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"msg": "routeGroup2"})
})
}
*/
r.Run(":9090")
}
标签:SET,Context,中间件,gin,m1,func,m2,GIN 来源: https://www.cnblogs.com/oxspirt/p/15388470.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。