当前位置: 首页 > news >正文

【Golang】——Gin 框架中间件详解:从基础到实战

中间件是 Web 应用开发中常见的功能模块,Gin 框架支持自定义和使用内置的中间件,让你在请求到达路由处理函数前进行一系列预处理操作。这篇博客将涵盖中间件的概念、内置中间件的用法、如何编写自定义中间件,以及在实际应用中的一些最佳实践。


文章目录

    • 1. 什么是中间件?
      • 1.1 中间件的概念
      • 1.2 Gin 中的中间件
    • 2. Gin 的内置中间件
      • 2.1 日志中间件 `Logger`
        • 使用方法
      • 2.2 恢复中间件 `Recovery`
        • 示例代码
    • 3. 自定义中间件
      • 3.1 创建一个简单的自定义中间件
      • 3.2 将自定义中间件应用到路由
    • 4. 常见中间件示例
      • 4.1 请求时间记录中间件
      • 4.2 认证中间件
      • 4.3 IP 限制中间件
    • 5. 路由组中的中间件
    • 6. 中间件应用顺序
    • 7. 中间件的实际应用建议
    • 8. 总结

在这里插入图片描述

1. 什么是中间件?

1.1 中间件的概念

中间件是一种拦截 HTTP 请求的处理机制,通常用于在请求到达最终处理函数之前进行操作。通过中间件可以进行认证、日志记录、错误处理等操作,并且可以控制请求是否继续传递给下一个中间件或路由处理函数。

1.2 Gin 中的中间件

在 Gin 框架中,中间件通过 gin.HandlerFunc 类型实现,能够在整个应用或特定的路由组上使用。Gin 默认提供了日志和恢复功能的中间件,用户也可以自定义其他功能的中间件。

2. Gin 的内置中间件

2.1 日志中间件 Logger

Logger 中间件用于记录每个请求的基本信息,包括请求路径、请求方法、请求状态码、响应时间等。这对于监控应用和调试问题非常有用。

使用方法
package mainimport ("github.com/gin-gonic/gin"
)func main() {r := gin.Default() // 默认包含 Logger 和 Recovery 中间件// 简单的路由示例r.GET("/ping", func(c *gin.Context) {c.String(200, "pong")})r.Run(":8080")
}

gin.Default() 方法自动包含 Logger 中间件,无需额外配置。每当有请求时,Logger 会在终端中显示请求的详细信息。

2.2 恢复中间件 Recovery

Recovery 中间件用于捕获应用中的 panic 并恢复正常运行状态,避免因为未捕获的异常而导致服务器崩溃。它会将错误信息记录下来并返回 500 状态码。

示例代码
package mainimport ("github.com/gin-gonic/gin"
)func main() {r := gin.Default() // 默认包含 Recovery 中间件r.GET("/panic", func(c *gin.Context) {panic("模拟服务器崩溃") // 触发 panic})r.Run(":8080")
}

在这个示例中,如果访问 /panic 路径,服务器会触发 panic,但由于 Recovery 中间件的存在,应用不会崩溃,用户将收到一个 500 错误响应,并且错误信息会被记录到日志中。

3. 自定义中间件

3.1 创建一个简单的自定义中间件

在 Gin 中,自定义中间件可以通过定义一个 gin.HandlerFunc 类型的函数来实现。以下是一个简单的示例,在每次请求前后打印日志信息:

func myMiddleware() gin.HandlerFunc {return func(c *gin.Context) {// 请求前println("请求开始")// 继续到下一个中间件或处理函数c.Next()// 请求后println("请求结束")}
}

3.2 将自定义中间件应用到路由

func main() {r := gin.Default()// 全局应用中间件r.Use(myMiddleware())r.GET("/ping", func(c *gin.Context) {c.String(200, "pong")})r.Run(":8080")
}

当访问 /ping 时,会在请求前后分别打印“请求开始”和“请求结束”,说明中间件在请求处理前后都能执行自定义逻辑。

4. 常见中间件示例

4.1 请求时间记录中间件

此中间件会记录每个请求的处理时间,用于监控慢请求:

func requestTimingMiddleware() gin.HandlerFunc {return func(c *gin.Context) {startTime := time.Now()c.Next() // 继续到下一个中间件或处理函数endTime := time.Now()latency := endTime.Sub(startTime)println("请求处理时间:", latency)}
}

requestTimingMiddleware() 应用到路由后,每个请求的处理时间会在终端打印。

4.2 认证中间件

此中间件用于验证用户是否携带有效的 Authorization 头信息。若未携带或无效,则直接返回 401 错误。

func authMiddleware() gin.HandlerFunc {return func(c *gin.Context) {token := c.GetHeader("Authorization")if token != "Bearer your_secret_token" {c.JSON(401, gin.H{"error": "Unauthorized"})c.Abort() // 停止后续处理return}c.Next()}
}

在需要认证的路由上使用该中间件,确保只有携带正确令牌的请求可以继续。

func main() {r := gin.Default()// 应用认证中间件到特定路由r.GET("/protected", authMiddleware(), func(c *gin.Context) {c.JSON(200, gin.H{"message": "认证通过,欢迎访问!"})})r.Run(":8080")
}

4.3 IP 限制中间件

实现一个简单的 IP 限制中间件,允许或禁止特定 IP 地址访问:

func ipRestrictionMiddleware(allowedIP string) gin.HandlerFunc {return func(c *gin.Context) {clientIP := c.ClientIP()if clientIP != allowedIP {c.JSON(403, gin.H{"error": "Forbidden"})c.Abort() // 停止后续处理return}c.Next()}
}

使用示例:

func main() {r := gin.Default()// 仅允许指定 IP 访问r.GET("/admin", ipRestrictionMiddleware("192.168.1.100"), func(c *gin.Context) {c.JSON(200, gin.H{"message": "欢迎访问管理员页面"})})r.Run(":8080")
}

5. 路由组中的中间件

Gin 允许在路由组中使用中间件,适用于对特定前缀的路由应用同一中间件。例如,我们可以对所有 /admin 路由使用认证中间件:

adminGroup := r.Group("/admin")
adminGroup.Use(authMiddleware())
{adminGroup.GET("/dashboard", func(c *gin.Context) {c.JSON(200, gin.H{"message": "欢迎来到管理员仪表盘"})})adminGroup.GET("/settings", func(c *gin.Context) {c.JSON(200, gin.H{"message": "管理员设置页面"})})
}

所有 /admin 开头的路由都需要通过认证。

6. 中间件应用顺序

在 Gin 中,中间件是按照注册的顺序依次执行的,执行顺序为先前后后。如果中间件 A 注册在 B 之前,那么 A 会在 B 之前执行;如果 c.Abort() 被调用,后续中间件将不会执行。

7. 中间件的实际应用建议

  • 认证中间件:应用到需要认证的路由。
  • 日志中间件:应用到所有路由,用于全局请求记录。
  • 限流和防护中间件:用于防止频繁请求,保护 API 资源。
  • 错误处理中间件:捕获并记录错误,确保应用不会因为异常而崩溃。

8. 总结

通过本篇博客,我们详细介绍了 Gin 中中间件的概念、使用方法,以及如何实现和应用自定义中间件。掌握中间件的使用方法后,你将可以更好地控制请求的处理流程,实现如认证、日志记录、限流等高级功能。在下一篇中,我们将深入探讨 Gin 框架的模板渲染功能,帮助你构建更丰富的 Web 应用界面。


相关文章:

【Golang】——Gin 框架中间件详解:从基础到实战

中间件是 Web 应用开发中常见的功能模块,Gin 框架支持自定义和使用内置的中间件,让你在请求到达路由处理函数前进行一系列预处理操作。这篇博客将涵盖中间件的概念、内置中间件的用法、如何编写自定义中间件,以及在实际应用中的一些最佳实践。…...

量子计算来袭:如何保护未来的数字世界

目录 前言 一、量子计算安全的学习方向 1. 量子物理学基础 2. 量子计算原理与技术 3. 传统网络安全知识 4. 量子密码学 5. 量子计算安全政策与法规 二、量子计算的漏洞风险 1. 加密算法被破解风险 2. 区块链安全风险 3. 量子密钥分发风险 4. 量子计算系统自身风险 …...

VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源

VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源 由于需要在 Linux 环境下进行一些测试工作,于是决定使用 VMware 虚拟化软件来安装 Ubuntu 24.04 .1操作系统。考虑到测试过程中需要访问 Github ,要使用Docker拉去镜像等外部网络资源,因此产…...

光伏电站仿真系统的作用

光伏仿真系统有多方面的重要作用,不仅对前期的项目设计评估还是后期的运维效验都有非常重要的作用。 1、优化系统设计 通过输入不同的光伏组件参数、布局方案以及气象条件等,模拟各种设计场景下光伏电站的性能表现。例如,可以比较不同类型光…...

Golang文件操作

写文件   os模块可以创建文件,使用fmt可以写入文件。如以下例子: package mainimport ("fmt""os" )func main() {// 学习 golang的文件操作file, err : os.Create("test.txt")if err ! nil {fmt.P…...

爬虫开发工具与环境搭建——使用Postman和浏览器开发者工具

第三节:使用Postman和浏览器开发者工具 在网络爬虫开发过程中,我们经常需要对HTTP请求进行测试、分析和调试。Postman和浏览器开发者工具(特别是Network面板和Console面板)是两种最常用的工具,能够帮助开发者有效地捕…...

React(二)

文章目录 项目地址七、数据流7.1 子组件传递数据给父组件7.1.1 方式一:給父设置回调函数,传递给子7.1.2 方式二:直接将父的setState传递给子7.2 给props传递jsx7.2.1 方式一:直接传递组件给子类7.2.2 方式二:传递函数给子组件7.3 props类型验证7.4 props的多层传递7.5 cla…...

同步原语(Synchronization Primitives)

同步原语(Synchronization Primitives)是用于控制并发编程中多个线程或进程之间的访问顺序,确保共享资源的安全访问的一组机制或工具。它们解决了竞争条件(Race Condition)、死锁(Deadlock)等并…...

SpringBoot服务多环境配置

一个项目的的环境一般有三个:开发(dev)、测试(test)、生产(proc),一般对应三套环境,三套配置文件。 像下面这样直接写两个配置文件是不行的。 application.ymlserver:port: 8080application-dev.ymlspring:datasource:driver-class-name: co…...

STM32单片机CAN总线汽车线路通断检测-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 1.电路图采用Altium Designer进行设计: 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着汽车电子技术的不断发展,车辆通信接口在汽车电子控…...

【环境搭建】使用IDEA远程调试Docker中的Java Web

有时候要对Docker的Java Web远程调试其功能,于是就需要使用IDEA的远程调试功能,记录一下简单配置方法。 以Kylin4.0.0为例,首先拉取镜像并启动容器: $ docker pull apachekylin/apache-kylin-standalone:4.0.0$ docker run -d \-…...

贴代码框架PasteForm特性介绍之select,selects,lselect和reload

简介 PasteForm是贴代码推出的 “新一代CRUD” ,基于ABPvNext,目的是通过对Dto的特性的标注,从而实现管理端的统一UI,借助于配套的PasteBuilder代码生成器,你可以快速的为自己的项目构建后台管理端!目前管…...

STM32G4的数模转换器(DAC)的应用

目录 概述 1 DAC模块介绍 2 STM32Cube配置参数 2.1 参数配置 2.2 项目架构 3 代码实现 3.1 接口函数 3.2 功能函数 3.3 波形源代码 4 DAC功能测试 4.1 测试方法介绍 4.2 波形测试 概述 本文主要介绍如何使用STM32G4的DAC模块功能,笔者使用STM32Cube工具…...

SpringMVC跨线程获取requests请求对象(子线程共享servletRequestAttributes)和跨线程获取token信息

文章目录 引言I 跨线程共享数据跨线程获取requests请求对象基于org.slf4j.MDC存储共享数据InheritableThreadLocal解决异步线程,无法获取token信息问题II Feign 传递请求属性feign 模块处理被调用方处理请求头III 异步调用的方式CompletableFutureAsync注解Executors引言 本文…...

提取repo的仓库和工作树(无效)

问题 从供应商处获取的.repo的git仓库裸(project-object)仓库和工作树(projects)是分开的。 解决方案 根据工作树的软链接路劲,将工作树合并到project-object下。 import os import shutil import argparse import logging# 设置日志配置 logging.basicConfig(l…...

力扣整理版七:二叉树(待更新)

满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。深度为k,有2^k-1个节点的二叉树。 完全二叉树:在完全二叉树中,除了最底层节点可能没填满外&am…...

基于单片机的多功能环保宠物窝设计

本设计基于单片机设计的多功能环保宠物窝,利用温湿度传感器、压力传感模块、气味传感模块、红外测温传感器、通信模块、显示模块、清扫部件等,使其能够实现自动检测并调节温湿度、补充宠物食物、检测宠物体温健康并出现异常时进行报警、自动清扫消毒宠物…...

HBase 基础操作

一、启动HBase 首先,确保Hadoop和HBase服务已经启动。如果尚未启动,可以使用以下命令启动: # 启动Hadoop start-all.sh# 启动HBase start-hbase.sh二、HBase Shell操作 创建表 在HBase Shell中,使用create命令创建表。以下是一…...

小米顾此失彼:汽车毛利大增,手机却跌至低谷

科技新知 原创作者丨依蔓 编辑丨蕨影 三年磨一剑的小米汽车毛利率大增,手机业务毛利率却出现下滑景象。 11月18日,小米集团发布 2024年第三季度财报,公司实现营收925.1亿元,同比增长30.5%,预估902.8亿元;…...

PCL 三维重建 a-shape曲面重建算法

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 Concave Hull重建 2.1.2 可视化曲面重建结果 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇总(长期更新) 一、概述 …...

基于Intelli框架构建智能体应用:从核心原理到电商客服实战

1. 项目概述:从“智能节点”到“智能体”的进化 最近在开源社区里,一个名为 intelligentnode/Intelli 的项目引起了我的注意。乍一看这个名字,你可能会和我最初一样,把它理解为一个“智能节点”框架。但深入探究其代码仓库和设计…...

ANSYS Workbench网格进阶:巧用‘Face Meshing’与‘Sweep’扫掠,让你的轴承座仿真既快又准

ANSYS Workbench网格进阶:巧用‘Face Meshing’与‘Sweep’扫掠提升轴承座仿真效率 轴承座作为机械传动系统中的关键部件,其应力分布与变形分析的准确性直接影响设备可靠性评估。传统四面体网格虽能快速生成,但在应力集中区域往往需要极高密度…...

Lua RTOS在ESP32上的应用:从架构解析到物联网项目实战

1. 项目概述:当Lua遇上RTOS,为ESP32注入灵魂 如果你玩过ESP32,大概率用过Arduino框架或者乐鑫官方的ESP-IDF。前者简单易上手,但深度定制和实时性有限;后者功能强大专业,但C语言开发门槛不低,调…...

24小时近45亿美元!国产大模型融资狂欢,印奇与杨植麟分道扬镳谁能笑到最后?

向左与向右:两种战略路线的分野2026年5月的第二个交易周,国产大模型赛道融资刷新。5月7日,月之暗面获约20亿美元融资,投后估值超200亿美元,由美团龙珠领投等;5月8日消息,阶跃星辰将完成近25亿美…...

大型机场U型机坪推出等待点运行优化【附案例】

✨ 长期致力于机场、U型机坪区、推出等待点、运行程序优化、启发式算法研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅如需沟通交流,点击《获取方式》 (1)单通道U型机坪推出等待点位优化…...

DenseNet参数量比ResNet少?从Bottleneck和Transition层设计,聊聊模型轻量化的核心思路

DenseNet与ResNet参数效率对比:从结构设计看模型轻量化本质 在深度学习模型设计中,参数量与计算效率一直是工程师们关注的核心指标。当DenseNet首次提出时,许多研究者对其参数效率感到惊讶——看似复杂的密集连接结构,实际参数量却…...

上海交通大学用1万条数据打败了工业界巨头的AI搜索神器

这项由上海交通大学研究团队主导完成的研究,以技术报告形式于2026年5月5日发布在预印本平台arXiv,编号为arXiv:2605.04036v1。对这一领域有深入兴趣的读者可以通过该编号检索完整论文。**一个让整个AI圈子都有些意外的故事**先说一个背景:现在…...

Agentfiles:统一管理AI编码助手技能文件的Obsidian插件

1. 项目概述:一个为AI编码助手打造的“技能管理中心” 如果你和我一样,同时在使用Claude Code、Cursor、Windsurf这些新一代的AI编码助手,那你一定也面临过同样的困扰:每个工具都有自己的一套“技能”(Skills&#xf…...

仅限首批Beta开发者访问的Gemini Calendar高级API权限池即将关闭——现在掌握这6个私有端点将决定你团队的2025排期话语权

更多请点击: https://intelliparadigm.com 第一章:Gemini Google Calendar智能安排 Gemini 与 Google Calendar 的深度集成正在重塑日程管理范式。通过 Google Workspace 的授权 API 与 Gemini 的自然语言理解能力协同,用户可直接用日常语句…...

Tarjan算法:从DFS序到强连通分量的寻路指南(附C++实战与缩点技巧)

1. 从迷宫探索到强连通王国:Tarjan算法的生活隐喻 想象你正在探索一座巨大的迷宫,手里拿着粉笔和记事本。每走到一个新的岔路口,你就在墙上标记数字(第一个到的路口标1,第二个标2...),这就是DFS…...