路由中间件
Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。它以性能好、中间件支持灵活著称,非常适合用来构建微服务或 RESTful API 服务。下面我将提供三个使用 Gin 的路由中间件的完整示例。
示例 1: 简单的日志记录中间件
这个中间件会在每个请求处理前后打印日志信息,包括请求的方法、路径和响应状态码。
package main
import (
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
// Logger 返回一个日志中间件,用于记录HTTP请求的详细信息。
// 该中间件主要记录了请求的路径、查询字符串、响应状态码、客户端IP和请求处理时间。
// 它通过gin.HandlerFunc类型返回一个闭包函数,以便在Gin路由中使用。
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
// 记录请求开始时间
start := time.Now()
// 获取请求路径
path := c.Request.URL.Path
// 获取查询字符串
raw := c.Request.URL.RawQuery
// 处理请求前
c.Next() // 处理请求
// 处理请求后
// 记录请求结束时间
end := time.Now()
// 计算请求处理耗时
latency := end.Sub(start)
// 获取HTTP响应状态码
statusCode := c.Writer.Status()
// 获取客户端IP
clientIP := c.ClientIP()
// 打印日志信息
log.Printf("| %3d | %13v | %15s | %40s |",
statusCode, latency, clientIP, path+"?"+raw)
}
}
func main() {
// 初始化Gin默认引擎
r := gin.Default()
// 使用Logger中间件
r.Use(Logger())
// 定义一个模拟耗时操作的测试路由
r.GET("/test", func(c *gin.Context) {
// 模拟耗时操作
time.Sleep(5 * time.Second)
// 返回JSON响应
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
// 启动HTTP服务器,监听端口8080
r.Run(":8080")
}
示例 2: 认证中间件
这个中间件会检查每个请求中是否包含特定的 Authorization
header,并验证其值是否为预期的 token。
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
// AuthRequired 是一个中间件函数,用于验证请求是否具有有效的授权令牌。
// 它通过检查HTTP请求的头部中的 "Authorization" 字段是否匹配预设的令牌来实现。
// 如果令牌无效,它会中止请求并返回 "Unauthorized" 错误。
// 如果令牌有效,它会允许请求继续进行到下一个处理函数。
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
c.Request.Header.Set("Authorization", "my-secret-token")
token := c.GetHeader("Authorization")
fmt.Println("Token:", token)
if token != "my-secret-token" {
c.JSON(http.StatusUnauthorized, gin.H{
"error": "Unauthorized"})
c.Abort()
return
}
c.Next()
}
}
func main() {
r := gin.Default()
// 应用认证中间件到所有 /admin 路由
// 这里通过将 AuthRequired 作为参数传递给 r.Group 来实现,
// 确保所有以 "/admin" 开头的路由都受到保护,防止未经授权的访问。
admin := r.Group("/admin", AuthRequired())
{
// 定义 /admin/dashboard 路由的处理函数。
// 该函数仅在通过 AuthRequired 中间件的验证后执行,
// 确保只有拥有有效令牌的请求才能访问dashboard。
admin.GET("/dashboard", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Welcome to the dashboard"})
})
}
// 启动HTTP服务器,监听端口8080。
r.Run(":8080")
}
示例 3: 自定义恢复中间件
当应用程序遇到未捕获的异常(panic)时,这个中间件会捕获并恢复程序,返回一个标准的错误消息给客户端。
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
// CustomRecovery 自定义恢复中间件,用于捕获并处理panic
// 这个中间件的目的是当发生panic时,能够优雅地恢复并返回500错误响应
func CustomRecovery() gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if err := recover(); err != nil {
// 如果有 panic 发生,设置状态码为 500 并返回错误信息
c.Error(err.(error)).SetMeta("recovered")
c.AbortWithStatusJSON(http.StatusInternalServerError,
gin.H{
"error": "Internal Server Error"})
}
}()
c.Next()
}
}
func main() {
r :=