gin框架内容(三)--中间件

gin框架内容(三)--中间件

Gin框架允许开发者在处理请求的过程中,加入用户自己的函数。这个函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等

即比如,如果访问一个网页的话,不管访问什么路径都需要进行登录,此时就需要为所有路径的处理函数进行统一一个中间件

Gin中的中间件必须是一个gin.HandlerFunc类型

一、中间件的设置

1.1为路由单独注册中间件

复制代码
package main

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

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() //调用后续的处理函数,即indexHandler
	//Since是一个函数,传入的参数是(t Time),返回值是 Duration
	//Duration是一个自定义类型,即: type Duration int64
	cost := time.Since(start) //从开始时间到现在花费的时间
	fmt.Println(cost)

	fmt.Println("m1 out.........")
}

func main() {
	r := gin.Default()
	// m1处于indexHandler函数的前面,请求来之后,先走m1,再走index
	r.GET("/index", m1, indexHandler)

	_ = r.Run()
}

1.2为全局路由注册1个中间件

复制代码
定义的全局中间件,下面的每个路由调用都是经过这个全局中间件

1.3为全局路由注册2个中间件【多个中间件也是这样的思路】

复制代码
package main

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

func indexHandler(c *gin.Context) {
	fmt.Println("index.....")
	c.JSON(http.StatusOK, gin.H{
		"msg": "index",
	})
}

// 定义一个中间件m1
func m1(c *gin.Context) {
	fmt.Println("m1 in.........")
	start := time.Now()
	c.Next()
	cost := time.Since(start)
	fmt.Println(cost)
	fmt.Println("m1 out.........")
}

// 定义一个中间件m2
func m2(c *gin.Context) {
	fmt.Println("m2 in.........")
	c.Next()
	fmt.Println("m2 out.........")
}
func main() {
	r := gin.Default()
	//确定中间件中间的关系
	r.Use(m1, m2)
	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()
}

从上面的打印关系可以看出,先通过第一个中间件M1的"

复制代码
c.Next()的前半部分,然后在到M2,最后到index,然后在执行c.Next()的后半部分,

这就是一个中间件的链条

1.4中间件的后面路由停止执行

1.4.1终止执行1

复制代码
package main

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

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()
	cost := time.Since(start)
	fmt.Println(cost)
	fmt.Println("m1 out.........")
}

// 定义一个中间件
func m2(c *gin.Context) {
	fmt.Println("m2 in.........")
	c.Abort() //阻止调用后续的处理函数
	fmt.Println("m2 out.........")
}
func main() {
	r := gin.Default()
	r.Use(m1, m2)
	r.GET("/index", indexHandler)
	r.GET("/shop", func(c *gin.Context) {
		fmt.Println("1111")
		c.JSON(http.StatusOK, gin.H{
			"msg": "shop",
		})
	})
	r.GET("/user", func(c *gin.Context) {
		fmt.Println("222222222")
		c.JSON(http.StatusOK, gin.H{
			"msg": "user",
		})
	})
	_ = r.Run()
}

因为m2中有个"

复制代码
c.Abort() //阻止调用后续的处理函数

"阻止后续内容执行,到这里就是返回了,根本执行不到后续路由信息

1.4.2终止执行2 return

1.5数据传递

在中间件里做一些操作,然后在处理函数里拿到或者其它的中间件里拿到对应的数据

复制代码
package main

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

func indexHandler(c *gin.Context) {
	fmt.Println("index.....")
	//Get是*Context的方法 传入的参数是(key string) ,返回值是(value interface{}, exists bool)
	name, ok := c.Get("name")
	if !ok {
		name = "匿名用户"
	}
	c.JSON(http.StatusOK, gin.H{
		"msg": name,
	})
}

// 定义一个中间件
func m1(c *gin.Context) {
	fmt.Println("m1 in.........")
	start := time.Now()
	c.Next()
	cost := time.Since(start)
	fmt.Println(cost)
	name, ok := c.Get("name")
	if !ok {
		name = "匿名用户"
	}
	fmt.Println(name)
	fmt.Println("m1 out.........")
}

// 定义一个中间件
func m2(c *gin.Context) {
	fmt.Println("m2 in.........")
	c.Set("name", "tom")
	fmt.Println("m2 out.........")
}
func main() {
	r := gin.Default()
	r.Use(m1, m2)
	r.GET("/index", indexHandler)
	_ = r.Run()
}
相关推荐
真上帝的左手4 天前
30. 技术专题-‌应用框架组件-关系型数据库-MySQL-Mybatis
数据库·分布式·mysql·中间件·mybatis
9624564 天前
容器 RUNNING,为什么中间件仍不可用?ActiveMQ 与 Kafka/ZooKeeper 恢复实录
中间件·kafka·activemq
真上帝的左手4 天前
30. 技术专题-‌应用框架组件-缓存-Redis
数据库·redis·分布式·缓存·中间件
真上帝的左手4 天前
30. 技术专题-‌应用框架组件-搜索引擎-ES
大数据·分布式·elasticsearch·搜索引擎·中间件
kingx34 天前
BugKu PRA 渗透测试 2(Harry‘s Blog):9 Flag 全链实战复盘
中间件·渗透测试·log4j2·内网渗透·反序列化
皓月盈江4 天前
GO使用Gin框架实现模板定义、解析与渲染
linux·golang·go·gin·定义模板·解析模板·渲染模板
sun_weitao4 天前
用 FastAPI + MQTT 做一个 ESP32最小化跑通示例
中间件·vue·fastapi
码剑客5 天前
Gin+GORM+Redis 项目开发常见性能坑汇总(Go后端避坑指南)
redis·后端·golang·gin
真上帝的左手5 天前
12. 消息队列-Kafka进阶
分布式·中间件·kafka
车载中间件通信6 天前
[TC8测试]TCP_FLAGS_PROCESSING_06
数据库·网络协议·tcp/ip·中间件·tc8