6-Gin 路由详解 --[Gin 框架入门精讲与实战案例]
Gin 是一个用 Go 语言编写的 HTTP Web 框架,以其高性能和简洁的 API 而闻名。它提供了一套强大的路由功能,使得开发者可以轻松地定义 URL 路由规则,并将这些规则映射到具体的处理函数(handler)。以下是关于 Gin 路由的详细解析:
1. 基本路由
Gin 允许你非常简单地定义基本的路由。你可以为不同的 HTTP 方法(如 GET、POST 等)指定路径和相应的处理器。
package mainimport ("github.com/gin-gonic/gin"
)// main 是程序的入口点
func main() {// 创建一个默认的 Gin 路由器router := gin.Default()// 定义根路径的 GET 请求处理函数router.GET("/", func(c *gin.Context) {// 返回 HTTP 200 状态码和 "Hello World!" 字符串响应c.String(200, "Hello World!")})// 定义 /submit 路径的 POST 请求处理函数router.POST("/submit", func(c *gin.Context) {// 返回 HTTP 200 状态码和一个 JSON 响应,包含消息 "Form submitted"c.JSON(200, gin.H{"message": "Form submitted",})})// 监听并在 0.0.0.0:8080 上启动服务router.Run(":8080")
}

2. 参数化路由
Gin 支持在路径中使用参数,这允许你创建动态路由。
package mainimport ("github.com/gin-gonic/gin"
)// main 是程序的入口点
func main() {// 创建一个默认的 Gin 路由器router := gin.Default()// 路由处理函数,用于响应带有具体用户ID的GET请求router.GET("/user/:id", func(c *gin.Context) {// 提取URL参数中的id值id := c.Param("id")// 返回用户ID信息c.String(200, "User ID is %s", id)})// 使用通配符 :name 匹配任意字符直到斜杠或结尾router.GET("/file/*filepath", func(c *gin.Context) {// 提取URL参数中的filepath值filepath := c.Param("filepath")// 返回文件路径信息c.String(200, "File path is %s", filepath)})// 监听并在 0.0.0.0:8080 上启动服务router.Run(":8080")
}

3. 查询参数
除了路径参数外,还可以通过 c.Query() 方法获取 URL 查询参数。
package mainimport ("github.com/gin-gonic/gin"
)// main 是程序的入口点
func main() {// 创建一个默认的 Gin 路由器router := gin.Default()// RouterGET为/search路径定义了一个处理函数,用于处理GET请求。// 该函数接收一个*gin.Context参数c,代表HTTP请求的上下文。// 参数c包含了请求、响应、HTTP头等信息,并且是处理请求和写入响应的核心对象。router.GET("/search", func(c *gin.Context) {// 使用c.Query方法从请求的查询字符串中获取名为'q'的值。// 如果'q'不存在,该方法返回一个空字符串。query := c.Query("q")// 使用c.String方法向HTTP响应中写入一个格式化后的字符串。// 该方法的参数包括HTTP状态码(此处为200,表示OK)和格式化字符串以及相应的参数。c.String(200, "Search query is %s", query)})// 监听并在 0.0.0.0:8080 上启动服务router.Run(":8080")
}

4. 表单数据
对于 POST 请求,可以使用 c.PostForm() 来获取表单字段。
package mainimport ("github.com/gin-gonic/gin"
)// main 是程序的入口点
func main() {// 创建一个默认的 Gin 路由器router := gin.Default()// 处理 POST 请求的路由router.POST("/form", func(c *gin.Context) {// 获取表单数据中的 name 字段name := c.PostForm("name")// 获取表单数据中的 age 字段age := c.PostForm("age")// 返回处理结果c.String(200, "Name: %s, Age: %s", name, age)})// 监听并在 0.0.0.0:8080 上启动服务router.Run(":8080")
}

5. 分组路由
为了更好地组织代码,可以使用 Group 创建一组具有相同前缀的路由。
package mainimport ("github.com/gin-gonic/gin"
)func main() {// 创建默认的路由引擎router := gin.Default()// 创建一个名为 "api" 的分组路由,所有以 /api 开头的 URL 都会进入这个分组api := router.Group("/api"){// 为整个分组添加一个简单的日志中间件api.Use(func(c *gin.Context) {fmt.Println("API Middleware Called")c.Next()})// 定义一个 GET 路由,用于获取所有用户api.GET("/users", getUsers)// 定义一个带参数的 GET 路由,用于根据 ID 获取单个用户api.GET("/users/:id", getUserByID)}// 启动 HTTP 服务,默认监听端口是 8080router.Run(":8080")
}// 模拟获取所有用户的处理器
func getUsers(c *gin.Context) {users := []string{"Alice", "Bob", "Charlie"}c.JSON(200, users)
}// 模拟根据 ID 获取单个用户的处理器
func getUserByID(c *gin.Context) {id := c.Param("id")user := "User with ID " + idc.JSON(200, gin.H{"user": user})
}

6. 中间件
Gin 提供了中间件机制,可以在请求到达最终处理器之前对请求进行预处理。
package mainimport ("fmt""time""github.com/gin-gonic/gin"
)func main() {// 创建默认的路由引擎router := gin.Default()// 定义一个全局中间件,用于记录所有请求的时间戳和耗时router.Use(Logger())// 定义一个 GET 路由,访问根路径时返回 "Hello World!"router.GET("/", func(c *gin.Context) {c.String(200, "Hello World!")})// 定义另一个 GET 路由,模拟处理较慢的请求router.GET("/slow", func(c *gin.Context) {time.Sleep(2 * time.Second)c.String(200, "This was a slow request.")})// 启动 HTTP 服务,默认监听端口是 8080router.Run(":8080")
}// Logger 是一个自定义的中间件函数
func Logger() gin.HandlerFunc {return func(c *gin.Context) {// 记录开始时间start := time.Now()path := c.Request.URL.Pathraw := c.Request.URL.RawQuery// 处理请求前的操作fmt.Printf("Started %s %s\n", c.Request.Method, path)// 将请求传递给下一个中间件或处理器c.Next()// 处理请求后的操作end := time.Since(start)fmt.Printf("Completed %s in %v\n", path, end)// 如果有查询参数,则打印出来if raw != "" {fmt.Printf("With query: %s\n", raw)}}
}

7. 静态文件服务
在 Gin 框架中提供静态文件服务(如图片、CSS 文件、JavaScript 文件等)非常简单。你可以使用 router.Static() 方法来指定一个 URL 路径前缀和本地文件系统的目录,从而将静态文件暴露给客户端。
下面是一个简单的 Gin 应用程序示例,它展示了如何设置静态文件服务。
示例:Gin 静态文件服务简单示例
创建项目结构
首先,创建如下所示的项目结构:
my-gin-app/
├── main.go
└── static/├── css/│ └── style.css├── js/│ └── script.js└── images/└── logo.png
在这个例子中,static 文件夹包含了 CSS、JavaScript 和图片文件。
创建 main.go 文件
接下来,在 main.go 文件中编写代码来配置 Gin 以提供静态文件服务。
package mainimport ("github.com/gin-gonic/gin"
)func main() {// 创建默认的路由引擎router := gin.Default()// 提供静态文件服务// 这里的第一个参数是 URL 路径前缀,第二个参数是本地文件系统中的目录路径。// 访问 http://localhost:8080/static/css/style.css 将会返回 ./static/css/style.css 文件router.Static("/static", "./static")// 定义一个简单的根路径处理器,用于展示如何链接到静态资源router.GET("/", func(c *gin.Context) {c.HTML(200, "index.tmpl", nil)})// 加载 HTML 模板router.LoadHTMLGlob("templates/*")// 启动 HTTP 服务,默认监听端口是 8080router.Run(":8080")
}
创建 HTML 模板
为了展示如何链接到静态资源,我们还需要创建一个简单的 HTML 模板。在项目的根目录下创建一个名为 templates 的文件夹,并在里面添加一个名为 index.tmpl 的文件:
<!-- templates/index.tmpl -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Gin Static Files Example</title><!-- 链接到静态 CSS 文件 --><link rel="stylesheet" href="/static/css/style.css">
</head>
<body><h1>Welcome to the Gin Static Files Example!</h1><p>This page uses static files served by Gin.</p><!-- 显示静态图片 --><img src="/static/images/logo.png" alt="Logo"><!-- 包含静态 JavaScript 文件 --><script src="/static/js/script.js"></script>
</body>
</html>
添加静态资源
确保你的 static 文件夹中有以下内容:
-
static/css/style.css:包含一些基本的样式规则。/* static/css/style.css */ body {font-family: Arial, sans-serif;text-align: center;margin-top: 50px; } h1 {color: #333; } -
static/js/script.js:包含一段简单的 JavaScript 代码。// static/js/script.js console.log('Static JavaScript file loaded.'); -
static/images/logo.png:放置一张你想要显示的图片。
测试你的应用
保存所有文件后,在终端中运行以下命令启动应用程序:
go run main.go
然后你可以使用浏览器访问 http://localhost:8080/ 来查看页面。你应该能够看到样式化的 HTML 页面,并且控制台中会有来自 JavaScript 文件的日志信息。此外,页面上应该正确显示了 logo.png 图片。
总结
通过上述步骤,我们创建了一个简单的 Gin 应用程序,它可以提供静态文件服务。使用 router.Static() 方法可以轻松地将本地文件夹中的静态资源映射到 Web 上的 URL 路径。这对于开发和测试来说非常方便,也可以直接部署到生产环境中。

8. 错误处理
虽然 Gin 默认提供了简单的错误处理,但你也可以自定义错误页面或全局错误处理逻辑。
package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)func main() {// 创建默认的路由引擎router := gin.Default()// 定义一个 GET 路由,访问根路径时返回 "Hello World!"router.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "Hello World!")})// 定义一个可能引发错误的 GET 路由router.GET("/error", func(c *gin.Context) {// 模拟一个可能导致 panic 的操作panic("Something went wrong!")})// 自定义 404 页面router.NoRoute(func(c *gin.Context) {c.JSON(http.StatusNotFound, gin.H{"code": http.StatusNotFound,"message": "Sorry, the page you're looking for doesn't exist.",})})// 使用 recover 中间件来捕获任何导致 panic 的错误,并返回 500 状态码router.Use(func(c *gin.Context) {defer func() {if err := recover(); err != nil {// 如果发生 panic,记录错误信息并返回 500 状态码fmt.Printf("Panic occurred: %v\n", err)c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"code": http.StatusInternalServerError,"message": "Internal Server Error",})}}()c.Next()})// 启动 HTTP 服务,默认监听端口是 8080router.Run(":8080")
}

9. 加载模板
如果你的应用程序需要渲染 HTML 页面,Gin 支持加载和渲染模板。
router.LoadHTMLGlob("templates/*")
router.GET("/welcome", func(c *gin.Context) {c.HTML(http.StatusOK, "welcome.tmpl", gin.H{"title": "Main website",})
})
10. CORS 中间件
跨域资源共享 (CORS) 是一个常见的需求,Gin 提供了官方的 CORS 中间件来简化配置。
router.Use(cors.New(cors.Config{AllowOrigins: []string{"https://foo.com"},AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},AllowHeaders: []string{"Origin", "Content-Length", "Content-Type"},ExposeHeaders: []string{"FooBar"},AllowCredentials: true,
}))
总结
Gin 的路由系统设计得非常直观且强大,能够满足大多数 Web 应用的需求。通过上述方法,你可以轻松地构建出高效、可维护的 RESTful API 或完整的 Web 应用。根据你的具体应用场景,选择合适的路由策略和中间件组合,可以使开发过程更加流畅和高效。如果你有更复杂的需求,比如基于正则表达式的路由匹配等,Gin 也提供了足够的灵活性来进行扩展。
下载示例代码
Gin 框架入门精讲与实战案例代码
相关文章:
6-Gin 路由详解 --[Gin 框架入门精讲与实战案例]
Gin 是一个用 Go 语言编写的 HTTP Web 框架,以其高性能和简洁的 API 而闻名。它提供了一套强大的路由功能,使得开发者可以轻松地定义 URL 路由规则,并将这些规则映射到具体的处理函数(handler)。以下是关于 Gin 路由的…...
使用Lodash工具库的orderby和sortby进行排序的区别
简介 _.orderBy 和 _.sortBy 是 Lodash 库中用于排序数组的两个函数。 区别 _.orderBy 允许你指定一个或多个属性来排序,并为每个属性指定排序方向(升序或降序)。默认所有值为升序排,指定为"desc" 降序,…...
CSS面试题|[2024-12-24]
1.说一下CSS的盒模型 在HTML页面中的所有元素都可以看成是一个盒子 盒子的组成:内容content、内边距padding、边框border、外边距margin 盒模型的类型: 标准盒模型 margin border padding content IE盒模型 margin content(包括border p…...
flask-admin 在modelview 视图中重写on_model_change 与after_model_change
背景: 当我们在使用flask-admin进行WEB开发时应该第一时间想到的是竟可能使用框架推荐的modelView模型,其次才是自定义模型 baseview,因为只有modelview模型下开发才能最大限度的提高效率。 制作: 1、在modelview视图下框架会通过默认视图…...
Excel粘贴复制不完整的原因以及解决方法
在数据处理和分析的过程中,Excel无疑是不可或缺的工具。然而,在使用Excel进行复制粘贴操作时,有时会遇到粘贴不完整的情况,这可能会让人感到困惑和烦恼。本文将深入探讨Excel粘贴复制不完整的原因、提供解决方案,并给出…...
【深度学习环境】NVIDIA Driver、Cuda和Pytorch(centos9机器,要用到显示器)
文章目录 一 、Anaconda install二、 NIVIDIA driver install三、 Cuda install四、Pytorch install 一 、Anaconda install Step 1 Go to the official website: https://www.anaconda.com/download Input your email and submit. Step 2 Select your version, and click i…...
Cocos Creator 3.8.5 正式发布,更小更快更多平台!
在 Cocos Creator 3.8.5 版本中,我们做了新一轮的优化。 在加载速度、代码裁剪、平台增强等多方面做了优化,提升了开发者体验和游戏性能。 希望能够助 Cocos 开发者们的产品更上一层楼。 一、加载速度优化 1、WASM 模块延迟加载 在早期版本中,…...
Python中构建终端应用界面利器——Blessed模块
在现代开发中,命令行应用已经不再仅仅是一个简单的文本输入输出工具。随着需求的复杂化和用户体验的重视,终端界面也逐渐成为一个不可忽视的设计环节。 如果你曾经尝试过开发终端UI,可能对传统的 print() 或者 input() 函数感到不满足&#…...
Android 15 状态栏闹钟图标不显示问题修复
Android 15 状态栏闹钟图标不显示问题修复 问题描述 在 Android 15 系统中,发现即使设置了闹钟,状态栏也不会显示闹钟图标。这个问题影响了用户及时查看闹钟状态的体验。 问题分析 通过查看 SystemUI 的配置文件,发现在 frameworks/base/packages/SystemUI/res/values/conf…...
数据采集背后的效率革命:如何优化你的爬虫性能
在爬虫技术日益发展的今天,性能优化成为提升数据采集效率的关键。面对日益复杂的网页结构和庞大的数据量,高效的爬虫能够显著降低运行时间和资源成本。本文将围绕爬虫性能优化的核心方法展开讨论,并通过实例对比多进程、多线程以及普通爬取的…...
【Compose multiplatform教程06】用IDEA编译Compose Multiplatform常见问题
当我们从Kotlin Multiplatform Wizard | JetBrains 下载ComposeMultiplatform项目时 会遇到无法正常编译/运行的情况,一般网页和桌面是可以正常编译的, 我这里着重解决如下问题 1:Gradle版本不兼容或者Gradle连接超时 2:JDK版本不兼容 3:Gradle依赖库连…...
《计算机组成及汇编语言原理》阅读笔记:p128-p132
《计算机组成及汇编语言原理》学习第 10 天,p128-p132 总结,总计 5 页。 一、技术总结 1.8088 organization and architecture 8088处理器是16位电脑,寄存器是16位,数据总线(data bus)是8位,地址总线是20位。 (1)g…...
使用 OpenCV 在图像中添加文字
在图像处理任务中,我们经常需要将文本添加到图像中。OpenCV 提供了 cv2.putText() 函数,可以很方便地在图像上绘制文本,支持多种字体、颜色、大小和位置等参数。 本文将详细介绍如何使用 OpenCV 在图像中添加文字,介绍 cv2.putTe…...
实现某海外大型车企(T)Cabin Wi-Fi 需求的概述 - 4
大家好,我是Q,邮箱:1042484520qq.com。 今天我们在上几讲的基础上再扩展下 Cabin Wi-Fi 的功能需求,讲讲如何使能 5G TCU Wi-Fi STA Bridge 模式。 参考: 实现某海外大型车企(T)Cabin Wi-Fi 需求…...
Linux系统:内核态与用户态的深层思考
背景: 我们学习Linux的系统调用经常会遇到一个概念:“内核态和用户态的切换”,一般人只会告诉你说这个切换代价很大,具体是什么情况?为什么需要切换?一定需要切换吗?怎么就会触发切换࿱…...
# 光速上手 - JPA 原生 sql DTO 投影
前言 使用 JPA 时,我们一般通过 Entity 进行实体类映射,从数据库中查询出对象。然而,在实际开发中,有时需要自定义查询结果并将其直接映射到 DTO,而不是实体类。这种需求可以通过 JPA 原生 SQL 查询和 DTO 投影 来实现…...
ASP.NET Web应用程序出现Maximum request length exceeded报错
一、问题描述 在ASP.NET的web应用中,导出数据时出现500 - Internal server error.Maximum request length exceeded。 二、原因分析 这个错误通常出现在Web应用程序中,表示客户端发送的HTTP请求的长度超过了服务器配置的最大请求长度限制。这可能是因为…...
HTML——16.相对路径
<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><a href"../../fj1/fj2/c.html" target"_blank">链接到c</a><!--相对路径:-->…...
windows 默认的消息ID有那些---我与大模型对话
前言: 与大模型交流,提问要尽量简短,突出关键词。否则它的回答就可能事是而非。用它总结和查资料还行,用它解决问题路还很远。它非常注重标准格式并机械的执行标准格式,并且事无巨细,不能灵活简要的回答问…...
CSV vs 数据库:爬虫数据存储的最佳选择是什么
介绍 在爬虫技术中,数据存储是一个不可缺少的环节。然而,选择合适的存储方式对数据分析和结果应用都致关重要。CSV和数据库是常用的两种存储方式,但它们各有优缺。这篇文章将分析两者在爬虫数据存储方面的选择值。 微博热搜是当前网络热点话…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
