Gin框架操作指南07:路由与中间件

官方文档地址(中文):https://gin-gonic.com/zh-cn/docs/
注:本教程采用工作区机制,所以一个项目下载了Gin框架,其余项目就无需重复下载,想了解的读者可阅读第一节:Gin操作指南:开山篇。
本节演示路由与中间件,包括路由参数;路由组;使用中间件;在中间件中使用Goroutine;自定义中间件。其中不使用默认的中间件很简单,就是使用
r := gin.New()代替r := gin.Default(),读者可自行演示。在开始之前,我们需要在”03路由与中间件“目录下打开命令行,执行如下命令来创建子目录:

mkdir 路由参数 路由组 使用中间件 在中间件中使用Goroutine 自定义中间件

目录

    • 一、路由参数
    • 二、路由组
    • 三、使用中间件
    • 四、在中间件中使用Goroutine
    • 五、自定义中间件

一、路由参数

package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {// 创建 Gin 路由实例router := gin.Default()// 路由匹配模式为 /user/:name// ":name" 是路由参数,可以匹配具体的用户名,例如 /user/john// 此 handler 将匹配像 /user/john 这样的 URL,但是不会匹配 /user/ 或者 /userrouter.GET("/user/:name", func(c *gin.Context) {// 使用 c.Param 获取路由中的参数 "name"name := c.Param("name")// 返回包含该 name 的字符串作为响应c.String(http.StatusOK, "Hello %s", name)})// 路由匹配模式为 /user/:name/*action// ":name" 是路由参数,可以匹配具体的用户名,例如 /user/john// "*action" 是通配符参数,表示匹配从指定路径开始的所有路径片段,例如 /user/john/send 或 /user/john/anything_else// 如果路径为 /user/john 并且没有其他路由匹配,Gin 会自动将其重定向到 /user/john/router.GET("/user/:name/*action", func(c *gin.Context) {// 获取路由参数 "name" 的值name := c.Param("name")// 获取通配符参数 "action" 的值,该值匹配路径中 "name" 后面的所有部分action := c.Param("action")// 拼接 name 和 action 作为响应的消息message := name + " is " + action// 返回拼接后的消息作为响应c.String(http.StatusOK, message)})// 启动 HTTP 服务器,监听 8080 端口router.Run(":8080")
}

效果
在这里插入图片描述

二、路由组

package mainimport ("net/http""github.com/gin-gonic/gin"
)// loginEndpoint 处理登录请求的示例处理函数
func loginEndpoint(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "Login successful"})
}// submitEndpoint 处理提交请求的示例处理函数
func submitEndpoint(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "Submit successful"})
}// readEndpoint 处理读取请求的示例处理函数
func readEndpoint(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "Read successful"})
}func main() {// 创建一个默认的 Gin 路由器router := gin.Default()// 定义第一个路由组 "v1"。所有 v1 组中的路由将以 "/v1" 开头v1 := router.Group("/v1"){// v1 组下的 POST 请求路由,处理 /v1/login,调用 loginEndpoint 处理函数v1.POST("/login", loginEndpoint)// v1 组下的 POST 请求路由,处理 /v1/submit,调用 submitEndpoint 处理函数v1.POST("/submit", submitEndpoint)// v1 组下的 POST 请求路由,处理 /v1/read,调用 readEndpoint 处理函数v1.POST("/read", readEndpoint)}// 定义第二个路由组 "v2"。所有 v2 组中的路由将以 "/v2" 开头v2 := router.Group("/v2"){// v2 组下的 POST 请求路由,处理 /v2/login,调用 loginEndpoint 处理函数v2.POST("/login", loginEndpoint)// v2 组下的 POST 请求路由,处理 /v2/submit,调用 submitEndpoint 处理函数v2.POST("/submit", submitEndpoint)// v2 组下的 POST 请求路由,处理 /v2/read,调用 readEndpoint 处理函数v2.POST("/read", readEndpoint)}// 启动 HTTP 服务器,监听 8080 端口router.Run(":8080")
}

效果
在这里插入图片描述
在这里插入图片描述

三、使用中间件

package mainimport ("log""time""github.com/gin-gonic/gin"
)// MyBenchLogger 是自定义的中间件,用于在路由上输出耗时信息
func MyBenchLogger() gin.HandlerFunc {return func(c *gin.Context) {t := time.Now()// 继续处理请求c.Next()// 处理结束后,计算请求的耗时并输出日志latency := time.Since(t)log.Print(latency)}
}// AuthRequired 是模拟的中间件,通常用于验证用户是否通过身份认证
func AuthRequired() gin.HandlerFunc {return func(c *gin.Context) {// 这里可以编写检查用户身份的逻辑// 如果用户未通过身份验证,可以使用 `c.Abort()` 停止请求处理链log.Println("AuthRequired middleware executed")// 继续处理请求c.Next()}
}// 模拟的处理器函数
func benchEndpoint(c *gin.Context) {// 这是实际的处理逻辑,返回一个简单的文本响应c.String(200, "Benchmark endpoint")
}func loginEndpoint(c *gin.Context) {// 登录处理逻辑,返回一个简单的文本响应c.String(200, "Login successful")
}func submitEndpoint(c *gin.Context) {// 表单提交处理逻辑,返回一个简单的文本响应c.String(200, "Form submitted")
}func readEndpoint(c *gin.Context) {// 数据读取处理逻辑,返回一个简单的文本响应c.String(200, "Data read")
}func analyticsEndpoint(c *gin.Context) {// 嵌套路由组处理逻辑,用于处理特定功能,例如数据分析c.String(200, "Analytics data")
}func main() {// 新建一个没有任何默认中间件的路由r := gin.New()// 全局中间件// Logger 中间件会记录请求的日志,写入 gin.DefaultWriter (默认是 os.Stdout)r.Use(gin.Logger())// Recovery 中间件会自动捕获请求中的 panic,并返回 500 错误r.Use(gin.Recovery())// 可以为特定路由使用中间件,这里为 "/benchmark" 路由添加了自定义的 MyBenchLogger 中间件r.GET("/benchmark", MyBenchLogger(), benchEndpoint)// 认证路由组 authorized,通过 AuthRequired 中间件来控制访问权限authorized := r.Group("/")// 使用自定义的 AuthRequired 中间件来保护这个路由组authorized.Use(AuthRequired()){// 这些路由都属于 authorized 路由组,并且会执行 AuthRequired 中间件authorized.POST("/login", loginEndpoint)authorized.POST("/submit", submitEndpoint)authorized.POST("/read", readEndpoint)// 嵌套路由组 testing,所有在此路由组下的路由也会执行 AuthRequired 中间件testing := authorized.Group("testing")testing.GET("/analytics", analyticsEndpoint)}// 启动 HTTP 服务,监听端口 8080r.Run(":8080")
}

GET效果
在这里插入图片描述
在这里插入图片描述

POST效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、在中间件中使用Goroutine

package mainimport ("log""time""github.com/gin-gonic/gin"
)func main() {// 初始化 Gin 默认实例,它包含了 Logger 和 Recovery 中间件r := gin.Default()// 异步处理r.GET("/long_async", func(c *gin.Context) {// 创建在 goroutine 中使用的副本// 由于上下文在 Goroutine 中被使用,必须通过 c.Copy() 拷贝一份上下文的副本。// 原因是 Gin 的上下文是有状态的,多 Goroutine 并发访问时不能共享原始上下文。cCp := c.Copy()// 启动 Goroutine 以模拟长任务go func() {// 用 time.Sleep 模拟一个耗时任务,执行 5 秒。time.Sleep(5 * time.Second)// 使用副本上下文来访问请求的路径信息// 如果直接使用原始上下文,可能会导致并发问题。log.Println("Done! in path " + cCp.Request.URL.Path)}()})// 同步处理r.GET("/long_sync", func(c *gin.Context) {// 同步处理时,没有 Goroutine,所以可以直接使用原始上下文。// 用 time.Sleep 模拟一个长任务,执行 5 秒。time.Sleep(5 * time.Second)// 输出请求路径log.Println("Done! in path " + c.Request.URL.Path)})// 启动服务器,监听在 0.0.0.0:8080r.Run(":8080")
}

打开浏览器
访问 http://localhost:8080/long_async 来测试异步处理,浏览器/Postman 会立即返回响应,不会等到 5 秒任务完成。控制台在 5 秒后会输出 Done! in path /long_async
在这里插入图片描述

访问 http://localhost:8080/long_sync 来测试同步处理。浏览器/Postman 会等到 5 秒任务完成后再返回响应。控制台会立即输出 Done! in path /long_sync
在这里插入图片描述

五、自定义中间件

package mainimport ("log""time""github.com/gin-gonic/gin"
)// Logger 自定义中间件,用于记录请求的延迟和状态
func Logger() gin.HandlerFunc {return func(c *gin.Context) {// 记录当前时间,用于计算请求延迟t := time.Now()// 设置一个名为 "example" 的上下文变量,其值为 "12345"c.Set("example", "12345")// 请求前的操作可以在这里进行// 例如:记录请求开始时间或执行一些检查// 处理请求,调用后续的处理函数c.Next()// 请求后的操作可以在这里进行// 计算请求处理的延迟latency := time.Since(t)// 打印延迟信息到日志log.Print(latency)// 获取并打印响应状态码status := c.Writer.Status()log.Println(status)}
}func main() {// 创建一个新的 Gin 实例,没有默认中间件r := gin.New()// 使用自定义的 Logger 中间件r.Use(Logger())// 定义一个 GET 路由 /testr.GET("/test", func(c *gin.Context) {// 从上下文中获取 "example" 变量,并进行类型断言example := c.MustGet("example").(string)// 打印获取到的 "example" 变量值:12345log.Println(example)})// 启动服务器,监听在 0.0.0.0:8080r.Run(":8080")
}

效果
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

武汉正向科技|焦炉移动机车连锁控制系统的介绍

焦炉车辆连锁控制系统是采用格雷母线定位技术,无线数据传输技术以及计算机技术,实现推焦车、拦焦车、熄焦车、装煤车、导烟车的集中监控和系统管理,以及车间作业计划管理,作业实绩管理,作业联锁控制及安全控制等。 焦炉…

超详细的finalshell安装数据库以及数据库的基本操作

一、下载 MySQL Enterprise Edition Downloads | Oraclehttps://www.oracle.com/mysql/technologies/mysql-enterprise-edition-downloads.html 这边有不同的版本,要看你的操作系统(centos7 / centos8)安装的是哪个版本 我把连接提取出来了&…

JAVA中类和对象

一.类的创建: 比如我们创建狗类: public class Dog {public String name; //名字public int age; //年龄public double tall; //身高//狗的行为public void bark() {System.out.println("汪汪汪~~~");}public void wag() {System.out.printl…

揭秘提升3DMAX效率的6款必备神级插件!

对于3DMax新手来说,掌握一些高效、实用的插件能够大大提升工作效率和创作质量。以下是6个不能错过的神级插件推荐: 第1个:3DMAX造山地形插件Mountain是一款专为3dMax设计的插件,旨在帮助用户轻松快速地创建逼真的山脉地形。以下是对该插件的详细介绍: 一、插件概述 Mou…

手写模拟Spring的基本功能

文章目录 1. Spring的基本功能2. 容器启动 容器启动,即创建容器对象并赋予配置对象3. BeanDefinition扫描4. Bean的生命周期5. 单例Bean与多例Bean6. 依赖注入7. AOP8. Aware 回调9. 初始化10. BeanPostProcessor附录: 1. Spring的基本功能 2. 容器启动 …

VSCode图标的含义,以及DataLoader代码的使用

1 问题 vscode中的那些图标的含义分别是什么Dataloader代码怎么做 2 方法 去网站里面搜索各种图形代表的含义然后进行理解和记忆 长方体:变量 紫色立方体: 库中预定义的枚举: 两个矩形块:枚举 自定义的枚举 橙色树状结构&#xff…

LinkedList和链表(上)

1. 顺序表ArrayList的缺点和优点 优点: 1> 在给定下标进行查找的时候,时间复杂度是O(1) 缺点: 1> 插入数据必须移动其他数据,最坏情况下,插入到0位置,时间复杂度为O(N) 2> 删除数据也需要移动数据,最坏情况下,就是删除0位置.时间复杂度为O(N) 3> 扩容之后(1.5倍扩容…

SQL JOIN的学习

SQL JOIN (w3school.com.cn) 之前跟着老师学数据库的时候学过,最近又比较频繁的在使用。 再复习一下。 Id_P是主键 Id_O是主键 1. SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons, Orders WHERE Persons.Id_P Orders.Id_P 2. SEL…

【JVM】—深入理解G1回收器——概念详解

深入理解G1回收器——概念详解 ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记链接👉https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~😊 文章目录 深入理解G1回收器…

保护企业终端安全,天锐DLP帮助企业智能管控终端资产

为有效预防员工非法调包公司的软硬件终端资产,企业管理员必须建立高效的企业终端安全管控机制,确保能够即时洞察并确认公司所有软硬件资产的状态变化。这要求企业要有一套能够全面管理终端资产的管理系统,确保任何未经授权的资产变动都能被迅…

Shiro认证 -- (Authentication)

Apache Shiro是一个功能强大的Java安全框架,提供了身份验证(Authentication)、授权(Authorization)、加密(Cryptography)、会话管理(Session Management)、与Web集成、缓…

【WEB应用安全测试指南–蓝队安全测试2】--超详细-可直接进行实战!!!亲测-可进行安全及渗透测试

安全基础理论入门知识参考上一篇《WEB应用安全测试指南蓝队安全测试1》 WEB应用安全测试指南2 一、文件 I/O 类1.1、任意文件上传1.2、任意文件下载1.3、文件包含 二、接口安全类2.1、短信炸弹2.2、邮件炸弹2.3、短信内容可控2.4、邮件内容可控 三、逻辑流程类3.1、越权3.2、未…

深度学习论文: EfficientCrackNet: A Lightweight Model for Crack Segmentation

深度学习论文: EfficientCrackNet: A Lightweight Model for Crack Segmentation EfficientCrackNet: A Lightweight Model for Crack Segmentation PDF: https://arxiv.org/pdf/2409.18099v1 PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: https:/…

红日安全vulnstack (一)

目录 环境搭建 本机双网卡 Kali IP 靶机IP Web GetShell 前期信息收集 Yxcms后台模板 Getshell PHPMyAdmin日志 Getshell into outfile写入一句话 X phpmyadmin 日志写入一句话 后渗透 MSF 生成木马上线 提取用户hash值 **hash**加密方式 MSF权限Shell至CS CS …

光标在单词中间,如何通过快捷键选择当前单词?

工具》选项>环境》键盘 :把应用修改成visual studio 6或者 visual assist就可以了

IO编程--单字符、字符串、格式化、模块化实现文件拷贝以及登录注册

一、完成标准io的单字符、字符串、格式化、模块化实现两个文件的拷贝 代码如下&#xff1a; 1.单字符 #include <myhead.h> int main(int argc, const char *argv[]) {//打开文件FILE* fpfopen("test.txt","r"); FILE* fqfopen("copy_test.txt&…

第九课:Python学习之函数基础

函数基础 目标 函数的快速体验函数的基本使用函数的参数函数的返回值函数的嵌套调用在模块中定义函数 01. 函数的快速体验 1.1 快速体验 所谓函数&#xff0c;就是把 具有独立功能的代码块 组织为一个小模块&#xff0c;在需要的时候 调用函数的使用包含两个步骤&#xff…

基于GRNN广义回归网络和MFCC的语音情绪识别matlab仿真,对比SVM和KNN

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) filePath Test_data\悲伤1.wav 类型&#xff1a;悲伤 识别置信度 Vmax 0.9559 2.算法运行软件版本 matlab2022a 3.部…

Vue2路由

1.路由 1.1.Vue路由基础 Vue属于单页应用&#xff08;SPA&#xff09;&#xff0c;即整个应用程序中只有一个html页面。 在单页应用中&#xff08;SPA&#xff09;&#xff0c;由于只是更改DOM来模拟多页面&#xff0c;所以页面浏览历史记录的功能就丧失了。此时&#xff0c…

nextjs项目中,使用postgres的完整案例

目的 通过此案例&#xff0c;可以简单快速的过一下数据库的操作&#xff0c;熟悉app-router这种模式下&#xff0c;client component和server component的两种组件中基本的接口使用。 技术栈 nextjs14.2.* app-routervercel/postgres0.10.*typescript5 重要事情说三遍1 ap…