Gin 框架中间件详细介绍

  1. 基本中间件结构:
// 基本中间件函数签名
func MiddlewareName() gin.HandlerFunc {return func(c *gin.Context) {// 处理请求前的逻辑c.Next()  // 处理下一个中间件或处理函数// 处理请求后的逻辑}
}
  1. 常用中间件示例:
package middlewareimport ("github.com/gin-gonic/gin""log""time"
)// 日志中间件
func Logger() gin.HandlerFunc {return func(c *gin.Context) {start := time.Now()path := c.Request.URL.Pathc.Next()latency := time.Since(start)statusCode := c.Writer.Status()log.Printf("Path: %s | Status: %d | Latency: %v", path, statusCode, latency)}
}// 认证中间件
func Auth() gin.HandlerFunc {return func(c *gin.Context) {token := c.GetHeader("Authorization")if token == "" {c.JSON(401, gin.H{"error": "Authorization token required"})c.Abort()return}// 验证 tokenif !validateToken(token) {c.JSON(401, gin.H{"error": "Invalid token"})c.Abort()return}c.Next()}
}// 错误处理中间件
func ErrorHandler() gin.HandlerFunc {return func(c *gin.Context) {defer func() {if err := recover(); err != nil {c.JSON(500, gin.H{"error": "Internal Server Error",})}}()c.Next()}
}// CORS 中间件
func CORS() gin.HandlerFunc {return func(c *gin.Context) {c.Writer.Header().Set("Access-Control-Allow-Origin", "*")c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")if c.Request.Method == "OPTIONS" {c.AbortWithStatus(204)return}c.Next()}
}
  1. 中间件的使用方式:
package mainimport ("github.com/gin-gonic/gin""your-project/middleware"
)func main() {r := gin.Default()// 全局中间件r.Use(middleware.Logger())r.Use(middleware.ErrorHandler())// 路由组中间件authorized := r.Group("/api")authorized.Use(middleware.Auth()){authorized.GET("/users", GetUsers)authorized.POST("/users", CreateUser)}// 单个路由中间件r.GET("/public", middleware.CORS(), PublicHandler)r.Run(":8080")
}
  1. 带配置的中间件:
// 限流中间件
func RateLimit(limit int, duration time.Duration) gin.HandlerFunc {limiter := rate.NewLimiter(rate.Every(duration), limit)return func(c *gin.Context) {if !limiter.Allow() {c.JSON(429, gin.H{"error": "Too many requests"})c.Abort()return}c.Next()}
}// 缓存中间件
func Cache(duration time.Duration) gin.HandlerFunc {cache := make(map[string]cacheEntry)type cacheEntry struct {data      interface{}timestamp time.Time}return func(c *gin.Context) {key := c.Request.URL.Path// 检查缓存if entry, exists := cache[key]; exists {if time.Since(entry.timestamp) < duration {c.JSON(200, entry.data)c.Abort()return}}c.Next()// 存储响应到缓存cache[key] = cacheEntry{data:      c.Keys["response"],timestamp: time.Now(),}}
}
  1. 自定义上下文:
// 自定义上下文
type CustomContext struct {*gin.ContextUser *models.User
}// 用户上下文中间件
func UserContext() gin.HandlerFunc {return func(c *gin.Context) {user := getCurrentUser(c)customContext := &CustomContext{Context: c,User:    user,}c.Set("custom_context", customContext)c.Next()}
}
  1. 链式中间件:
// 请求链路追踪
func RequestTracing() gin.HandlerFunc {return func(c *gin.Context) {traceID := generateTraceID()c.Set("trace_id", traceID)c.Next()// 记录请求完成log.Printf("Request completed: %s", traceID)}
}// 性能监控中间件
func Performance() gin.HandlerFunc {return func(c *gin.Context) {start := time.Now()c.Next()duration := time.Since(start)if duration > time.Second {log.Printf("Slow request: %s took %v", c.Request.URL.Path, duration)}}
}
  1. 中间件通信:
// 设置和获取中间件数据
func DataMiddleware() gin.HandlerFunc {return func(c *gin.Context) {// 设置数据c.Set("key", "value")c.Next()// 获取数据value, exists := c.Get("key")if exists {// 使用数据}}
}// 响应修改中间件
func ResponseModifier() gin.HandlerFunc {return func(c *gin.Context) {c.Next()// 修改响应status := c.Writer.Status()if status >= 400 {c.JSON(status, gin.H{"error":   true,"message": c.Keys["error"],})}}
}
  1. 高级中间件示例:
// JWT 认证中间件
func JWTAuth() gin.HandlerFunc {return func(c *gin.Context) {token := c.GetHeader("Authorization")if token == "" {c.JSON(401, gin.H{"error": "No token provided"})c.Abort()return}claims, err := parseToken(token)if err != nil {c.JSON(401, gin.H{"error": "Invalid token"})c.Abort()return}c.Set("user_id", claims.UserID)c.Next()}
}// 请求验证中间件
func ValidateRequest(schema interface{}) gin.HandlerFunc {return func(c *gin.Context) {if err := c.ShouldBindJSON(schema); err != nil {c.JSON(400, gin.H{"error": err.Error()})c.Abort()return}c.Set("validated_data", schema)c.Next()}
}// 请求限制中间件
func RequestLimit(maxRequests int, duration time.Duration) gin.HandlerFunc {clients := make(map[string][]time.Time)mu := &sync.Mutex{}return func(c *gin.Context) {ip := c.ClientIP()now := time.Now()mu.Lock()defer mu.Unlock()// 清理过期的请求记录clients[ip] = filterOldRequests(clients[ip], now.Add(-duration))if len(clients[ip]) >= maxRequests {c.JSON(429, gin.H{"error": "Too many requests"})c.Abort()return}clients[ip] = append(clients[ip], now)c.Next()}
}
  1. 测试中间件:
func TestAuthMiddleware(t *testing.T) {// 创建测试路由r := gin.New()r.Use(Auth())r.GET("/test", func(c *gin.Context) {c.JSON(200, gin.H{"message": "success"})})// 创建测试请求w := httptest.NewRecorder()req, _ := http.NewRequest("GET", "/test", nil)// 不带 token 的请求r.ServeHTTP(w, req)assert.Equal(t, 401, w.Code)// 带有效 token 的请求w = httptest.NewRecorder()req.Header.Set("Authorization", "valid-token")r.ServeHTTP(w, req)assert.Equal(t, 200, w.Code)
}
  1. 中间件最佳实践:
// 中间件工厂
type MiddlewareConfig struct {EnableLogging boolLogLevel     stringTimeout      time.Duration
}func NewMiddleware(config MiddlewareConfig) gin.HandlerFunc {return func(c *gin.Context) {if config.EnableLogging {// 启用日志}// 设置超时ctx, cancel := context.WithTimeout(c.Request.Context(), config.Timeout)defer cancel()c.Request = c.Request.WithContext(ctx)done := make(chan bool)go func() {c.Next()done <- true}()select {case <-done:returncase <-ctx.Done():c.JSON(504, gin.H{"error": "request timeout"})c.Abort()}}
}

使用这些中间件时,需要注意:

  • 中间件的执行顺序很重要
  • 合理使用 c.Next()c.Abort()
  • 避免在中间件中存储太多数据
  • 注意性能影响
  • 做好错误处理
  • 保持中间件的独立性和可复用性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/18434.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

三、计算机视觉_04AlexNet、VggNet、ResNet设计思想

1、AlexNet 1.1 基本介绍 AlexNet是由Alex Krizhevsky、Ilya Sutskever和Geoffrey Hinton在2012年ImageNet大规模视觉识别挑战赛&#xff08;ILSVRC&#xff09;中提出的&#xff0c;它不仅赢得了当届的比赛&#xff0c;还激发了后续许多创新的神经网络架构&#xff08;如VGGN…

基于SpringBoot的在线考试系统的设计与实现+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

LabVIEW三针自动校准系统

基于LabVIEW的智能三针自动校准系统采用非接触式激光测径仪对标准三针进行精确测量。系统通过LabVIEW软件平台与硬件设备的协同工作&#xff0c;实现了数据自动采集、处理及报告生成&#xff0c;大幅提高了校准精度与效率&#xff0c;并有效降低了人为操作误差。 一、项目背景…

群控系统服务端开发模式-应用开发-前端上传配置功能开发

一、添加视图 在根目录下src文件夹下views文件夹下param文件夹下system文件夹下&#xff0c;新建index.vue&#xff0c;代码如下 <template><el-tabs type"border-card"><el-tab-pane v-if"$store.getters.butts.includes(ParamSystemIndexDeta…

VAM本体整合包,本体人物卡

已更至2024年11月】全网人物卡最全&#xff01;所见即所得解压既玩。资源整合包较大&#xff0c;选择性下载想玩什么下什么&#xff01;&#xff01;&#xff01; 1.包含上千付费级精品场景&#xff0c;新增数位神佬合集&#xff0c;新增绝版素材。 2.没有场景是没有灵魂的&…

jmeter常用配置元件介绍总结之监听器

系列文章目录 1.windows、linux安装jmeter及设置中文显示 2.jmeter常用配置元件介绍总结之安装插件 3.jmeter常用配置元件介绍总结之线程组 4.jmeter常用配置元件介绍总结之函数助手 5.jmeter常用配置元件介绍总结之取样器 6.jmeter常用配置元件介绍总结之jsr223执行pytho…

蓝绿色电影风格滑板运动自拍照Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 蓝绿色电影风格的滑板运动自拍照&#xff0c;通过 Lightroom 调色&#xff0c;将滑板运动的活力与电影般的质感相结合。这种风格以独特的蓝绿色调为主&#xff0c;营造出一种神秘、宁静又充满活力的氛围&#xff0c;仿佛将瞬间定格成电影画面中的一帧。 预设信息 调…

通用定时器---输入捕获功能

目录 一、概念 二、输入捕获的结构图 三、配置的基本步骤 一、概念 STM32的输入捕获功能是一种强大的特性&#xff0c;他允许处理器捕获外部输入信号&#xff0c;并基于定时器抓取输入信号指定触发方式&#xff08;上升沿/下降沿&#xff09;之间的长度。这对于测量信号的脉…

Comsol 大功率超声波清洗机

大功率超声波清洗机是利用超声波在清洗液中产生的空化作用来清洗物体表面的设备。这种清洗机通常用于清洗工业零部件、实验器皿、医疗器械等物体&#xff0c;能够高效去除表面附着的污垢、油脂、细菌等。 大功率超声波清洗机的工作原理是通过超声波换能器将电能转换成机械振动…

计算机视觉中的双边滤波:经典案例与Python代码解析

&#x1f31f; 计算机视觉中的双边滤波&#xff1a;经典案例与Python代码解析 &#x1f680; Hey小伙伴们&#xff01;今天我们要聊的是计算机视觉中的一个重要技术——双边滤波。双边滤波是一种非线性滤波方法&#xff0c;主要用于图像去噪和平滑&#xff0c;同时保留图像的边…

模板——实现泛型编程的有力武器

模板——实现泛型编程的有力武器 我们为什么需要模板&#xff1f;模板 前言&#xff1a;关于模板&#xff0c;相信大家都有所而闻&#xff0c;以下是我对C模板的个人看法&#xff0c;希望能够帮助到你们呀&#xff01; 我们为什么需要模板&#xff1f; 请到大家看这一段代码&a…

Hugging_Face下载

能进huggingface的就能翻过去 不行的话可以去参考这个:mojie.app 1.直接原网下载 2.git(小白勿入) 如果是Linux&#xff0c;可以搜一个叫HFD&#xff08;HuggingFace_Download&#xff09; Windows的git安装参考如下&#xff1a;Git安装 建议先看看这个文档&#xff0c; 如果…

C++之内存管理

​ &#x1f339;个人主页&#x1f339;&#xff1a;喜欢草莓熊的bear &#x1f339;专栏&#x1f339;&#xff1a;C入门 目录 前言 一、C/C内存分配 二、 malloc、calloc、realloc、free 三、C内存管理方式 3.1 new/delete 操作内置类型 3.2 new和detele操作自定义类型…

QT适配最新版Android SDK

从AndroidStudio的SDK管理下载最新版SDK 从https://www.androiddevtools.cn/下载国内安卓SKDTools 这里下载SKDTools后不需要使用SDK Manager.exe下载SDK&#xff08;SDK Manager.exe下载的SDK都是旧版&#xff0c;没法支持新版本&#xff09;&#xff0c;直接使用从AndroidS…

Ubuntu 环境下通过 Apt-get 安装软件

操作场景 为提升用户在云服务器上的软件安装效率&#xff0c;减少下载和安装软件的成本&#xff0c;腾讯云提供了 Apt-get 下载源。在 Ubuntu 环境下&#xff0c;用户可通过 Apt-get 快速安装软件。对于 Apt-get 下载源&#xff0c;不需要添加软件源&#xff0c;可以直接安装软…

反转链表、链表内指定区间反转

反转链表 给定一个单链表的头结点pHead&#xff08;该头节点是有值的&#xff0c;比如在下图&#xff0c;它的val是1&#xff09;&#xff0c;长度为n&#xff0c;反转该链表后&#xff0c;返回新链表的表头。 如当输入链表{1,2,3}时&#xff0c;经反转后&#xff0c;原链表变…

SpringCloud篇(服务网关 - GateWay)

目录 一、简介 二、为什么需要网关 二、gateway快速入门 1. 创建gateway服务&#xff0c;引入依赖 2. 编写启动类 3. 编写基础配置和路由规则 4. 重启测试 5. 网关路由的流程图 6. 总结 三、断言工厂 四、过滤器工厂 1. 路由过滤器的种类 2. 请求头过滤器 3. 默认…

MATLAB实现历史模拟法计算VaR(Value at Risk)

MATLAB实现历史模拟法计算VaR(Value at Risk) 历史模拟法&#xff08;Historical Simulation Method&#xff09;是一种用于计算风险值&#xff08;Value at Risk, VaR&#xff09;的非参数方法。它基于过去的资产价格或收益数据来估计未来的潜在损失。 MATLAB代码如下: 完整…

数据结构——红黑树

目录 一.红黑树 二.红黑树的实现 1.红黑树节点的定义 2.红黑树的插入 3.红黑树的遍历 4.检测红黑树 5.红黑树的查找 6.红黑树的性能 三.整体代码 1.RBTree.h 2.RBTree.cpp 一.红黑树 1.红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上…

OMV7 树莓派 tf卡安装

​ 升级7之后&#xff0c;问题多多&#xff0c;不是docker不行了&#xff0c;就是代理不好使 今天又重装了一遍&#xff0c;用官方的链接&#xff0c;重新再折腾一遍…… 使用raspberry pi imager安装最新版lite OS。 注意是无桌面 Lite版 配置好树莓派初始化设置&#xff0…