当前位置: 首页 > 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点云算法与项目实战案例汇总(长期更新) 一、概述 …...

【Android】线程池的解析

引言 在Android当中根据用途分为主线程与子线程,主线程当中主要处理与界面相关的操作,子线程主要进行耗时操作。除了Thread本身以外,在Android当中还有很多扮演者线程的角色,比如AsyncTask( 底层为线程池,…...

集群聊天服务器(8)用户登录业务

目录 登录状态业务层代码数据模型层代码记录用户的连接信息以及线程安全问题客户端异常退出业务 登录状态 登录且状态变为online 业务层代码 #include "chatservice.hpp" #include "public.hpp" #include <string> #include <muduo/base/Loggi…...

Go语言中的错误嵌套

在Go语言中&#xff0c;错误处理是程序健壮性的关键。Go 1.13版本引入了错误值的嵌套和链式处理&#xff0c;使得错误信息的传递和处理更加灵活和强大。这种机制允许我们在错误中嵌套另一个错误&#xff0c;从而创建一个错误链&#xff0c;这有助于调试和错误跟踪。 错误嵌套的…...

51单片机基础 06 串口通信与串口中断

目录 一、串口通信 二、串口协议 三、原理图 四、串口通信配置参数 1、常用的串行口工作方式1 2、数据发送 3、数据接收 4、波特率计算 5、轮询接收 6、中断接收 一、串口通信 串口通信是一种常见的数据传输方式&#xff0c;广泛用于计算机与外部设备或嵌入式系统之间…...

Elasticsearch:更好的二进制量化(BBQ)对比乘积量化(PQ)

作者&#xff1a;来自 Elastic Benjamin Trent 为什么我们选择花时间研究更好的二进制量化而不是在 Lucene 和 Elasticsearch 中进行生产量化。 我们一直在逐步使 Elasticsearch 和 Lucene 的向量搜索变得更快、更实惠。我们的主要重点不仅是通过 SIMD 提高搜索速度&#xff0…...

【GNU】gcc -g编译选项 -g0 -g1 -g2 -g3 -gdwarf

1、gcc -g的作用 GCC 的 -g 选项用于在编译时生成调试信息&#xff0c;这些信息会嵌入到生成的目标文件或可执行文件中&#xff0c;主要目的是为了支持调试器&#xff08;如 gdb&#xff09;对程序的调试工作。 1.1 生成调试信息 当你在编译代码时使用 -g 选项&#xff0c;GCC…...

MySQL【六】

存储过程 存储过程是一组为了完成特定功能的 SQL 语句集&#xff0c;经编译创建并保存在数据库中&#xff0c;用户可通过指定存储过程的名字并给定参数&#xff08;需要时&#xff09;来调用执行。 简单的说存储过程就是具有名字的一段代码。 存储过程的创建 CREATE PROC[ED…...

杰发科技AC7801——ADC定时器触发的简单使用

使用场景 在需要多次采样结果的情况下&#xff0c;比如1s需要10w次的采样结果&#xff0c;可以考虑使用定时器触发采样&#xff0c;定时器设置多少的时间就会多久采样转换一次。 再加上使用dma&#xff0c;采样的结果直接放在dma的数组里面。 实现了自动采样&#xff0c;自动…...

VTK知识学习(8)-坐标系统

1、概述 计算机图形学里常用的坐标系统有4种&#xff1a; 1&#xff09;、Model坐标系统。定义模型时所采用的坐标系统&#xff0c;通常是局部的笛卡儿坐标系。 2&#xff09;、World坐标系统。是放置Actor的三维空间坐标系。 Actor&#xff08;vtkActor类&am…...

IO流部分串讲

一、IO流的概念简析&#xff1a; java将输入与输出比喻为"流"&#xff0c;英文:Stream. 就像生活中的"电流","水流"一样,它是以同一个方向顺序移动的过程.只不过这里流动的是字节(2进制数据).所以在IO中有输入流和输出流之分,我们理解他们是连接…...

做怎么样的网站好/贵阳百度快照优化排名

通过从运营商处非法获取用户cookie操纵公民社交账户强行加粉或关注涉嫌非法获取计算机信息系统数据罪行为模式分析及辩护策略车冲&#xff1a;广东法丞汇俊律师事务所刑事律师微信&#xff1a;18819352650相信不少人都遇到过微博自动关注陌生营销账号、QQ无缘无故添加陌生好友和…...

单页竞价网站/品牌软文案例

第五章&#xff1a;构建块 平台类库包含了一个并发构建块的丰富集合&#xff0c;比如线程安全容器和多种同步工具(Synchronizer)。 Synchronizer用来调节相互协作的线程间的控制流。 同步容器 同步容器类包括两部分&#xff0c;一个 是Vector和HashTable&#xff0c;它们是…...

成都有哪些网站建设/地推接单平台网

下面用自启动apache为例;自启动脚本:/usr/local/apache2/bin&#xff1b;./apachectl start文件位于/etc/rc.d/init.d下,名为apached, 注意要可执行.#chmod x /etc/rc.d/init.d/apached //设置文件的属性为可执行#ln -s /etc/rc.d/init.d/apached /etc/rc3.d/S90apache //建立软…...

做推广的免费的济宁网站有哪些/发帖子的网站

主要是解决在测试使用mongo db 时候&#xff0c;总是出现的MongoAuthenticationException 异常和 not authorized for query&#xff0c;not authorized on admin to execute command 等问题。 直接上测试步骤图拉。 我这个是先卸载了原来的mongo服务&#xff0c;然后删除我…...

怎么免费永久创建网站无广告/百度推广后台登录

要想完成一个中文词频统计功能&#xff0c;首先必须使用一个中文分词器&#xff0c;这里使用的是中科院的。下载地址是http://ictclas.nlpir.org/downloads&#xff0c;由于本人电脑系统是win32位的&#xff0c;因此下载的是 NLPIR-JNI-发布包.zip&#xff0c;解压之后导入myec…...

wordpress海报功能/今天的新闻联播

一&#xff1a;基础设施之日志打印实战代码一 1-3万行代码&#xff0c;想收获多少就要付出多少&#xff0c;平衡 注意代码的保护&#xff0c;私密性 日志的重要性&#xff1a;供日后运行维护人员去查看、定位和解决问题&#xff1b; 新文件&#xff1a;ngx_printf.cxx以及n…...