【Golang】——Gin 框架中的路由与请求处理
文章目录
- 1. 路由基础
- 1.1 什么是路由?
- 1.2 Gin 中的路由概述
- 2. 创建简单路由
- 2.1 基本路由定义
- 2.2 不同请求方法的路由
- 3. 路由参数
- 3.1 路径参数
- 3.2 查询参数
- 4. 路由分组
- 4.1 为什么使用路由分组?
- 4.2 路由分组示例
- 5. 请求处理与响应
- 5.1 Gin 中的 Context 对象
- 5.2 JSON 响应
- 5.3 常见的响应方法
- 6. 实践示例:创建用户管理 API
- 6.1 API 功能需求
- 6.2 完整代码
- 6.3 代码解释
- 6.4 运行与测试
- 7. 总结
1. 路由基础
1.1 什么是路由?
在 Web 开发中,路由是指 URL 与请求处理函数之间的映射关系。通过路由,可以将客户端请求的路径映射到服务器端的特定处理逻辑,从而根据不同的路径和请求方法执行不同的操作。例如,当用户访问 /products
页面时,服务器可以响应商品数据,而访问 /users
则响应用户数据。
1.2 Gin 中的路由概述
Gin 框架中的路由机制十分灵活,支持以下几种特性:
- 路径参数:路径中可以带有动态的部分,例如
/users/:id
,:id
会被识别为动态参数。 - 查询参数:通常在 URL 中
?
后面指定,用于传递额外信息,例如/search?query=gin
。 - 分组路由:将具有相同前缀的路由分组,便于管理,例如
/v1/users
、/v1/products
等。
2. 创建简单路由
2.1 基本路由定义
在 Gin 中,可以使用 r.GET
、r.POST
等方法为不同的 HTTP 请求类型创建路由。下面是一个简单的示例代码,创建一个 GET 请求路由来响应根路径:
package mainimport ("github.com/gin-gonic/gin"
)func main() {// 使用 gin.Default() 创建带有默认中间件(日志和恢复中间件)的路由r := gin.Default()// 创建一个 GET 路由,匹配根路径 "/"r.GET("/", func(c *gin.Context) {// 使用 c.String() 返回纯文本内容,状态码为 200c.String(200, "欢迎使用 Gin 框架!")})// 启动 HTTP 服务,监听 8080 端口r.Run(":8080")
}
解释:
r := gin.Default()
:使用gin.Default()
方法初始化一个 Gin 引擎实例,包含了日志和崩溃恢复中间件。r.GET("/", func(c *gin.Context) {...})
:定义一个 GET 请求路由,匹配根路径/
。c.String(200, "...")
:返回状态码为 200 的纯文本响应。
2.2 不同请求方法的路由
Gin 提供了多种路由方法,分别对应不同的 HTTP 请求方法:
- GET:用于请求资源,例如获取用户数据。
- POST:用于提交新数据,例如新建用户。
- PUT:用于更新已有数据,例如修改用户信息。
- DELETE:用于删除数据,例如删除用户。
以下代码展示了如何使用不同的请求方法:
r.GET("/users", func(c *gin.Context) {c.String(200, "获取用户列表")
})r.POST("/users", func(c *gin.Context) {c.String(200, "创建新用户")
})r.PUT("/users/:id", func(c *gin.Context) {id := c.Param("id")c.String(200, "更新用户 %s 的信息", id)
})r.DELETE("/users/:id", func(c *gin.Context) {id := c.Param("id")c.String(200, "删除用户 %s", id)
})
3. 路由参数
3.1 路径参数
路径参数是一种在路径中传递动态数据的方式。例如 /users/:id
,其中 :id
是一个动态参数,可以捕获并在处理函数中使用:
r.GET("/users/:id", func(c *gin.Context) {// 使用 c.Param("id") 获取路径参数 id 的值id := c.Param("id")c.String(200, "用户 ID 是 %s", id)
})
示例说明:
- 当用户访问
/users/123
时,c.Param("id")
将会返回"123"
。 - 可以通过
id := c.Param("id")
获取到路径参数的值,进行进一步操作。
3.2 查询参数
查询参数用于在 URL 中传递额外数据,通常在路径后加上 ?
。例如 /search?query=gin
,query
为查询参数名,值为 "gin"
。Gin 可以通过 c.Query("参数名")
获取查询参数。
r.GET("/search", func(c *gin.Context) {query := c.Query("query")page := c.DefaultQuery("page", "1") // 设置默认值为 "1"c.String(200, "查询内容:%s,页码:%s", query, page)
})
示例说明:
- 使用
c.Query("query")
获取query
参数的值。 c.DefaultQuery("page", "1")
如果没有提供page
参数,则使用默认值"1"
。
4. 路由分组
4.1 为什么使用路由分组?
路由分组用于将具有相同前缀的路由划分为一个组,便于管理。比如一个 API 可能会有不同版本 /v1
和 /v2
,在不同版本中定义相似的路由,可以简化代码。
4.2 路由分组示例
以下代码展示了如何创建带有 /v1
和 /v2
前缀的路由分组:
v1 := r.Group("/v1")
{v1.GET("/users", func(c *gin.Context) {c.String(200, "获取 v1 版本的用户列表")})v1.POST("/users", func(c *gin.Context) {c.String(200, "在 v1 中创建新用户")})
}v2 := r.Group("/v2")
{v2.GET("/users", func(c *gin.Context) {c.String(200, "获取 v2 版本的用户列表")})
}
示例说明:
/v1
组内定义了用户列表的 GET 和 POST 路由。/v2
组内定义了用户列表的 GET 路由。- 这样便于管理不同 API 版本的路由。
5. 请求处理与响应
5.1 Gin 中的 Context 对象
Gin 中的 Context
对象封装了请求和响应。我们可以通过 Context
来获取请求信息并设置响应内容。Context
包含的常用方法有:
c.Param("参数名")
:获取路径参数。c.Query("参数名")
:获取查询参数。c.PostForm("参数名")
:获取 POST 请求的表单参数。c.JSON()
、c.XML()
、c.String()
:设置不同类型的响应内容。
5.2 JSON 响应
Gin 的 c.JSON()
方法可以用来返回 JSON 格式的数据:
r.GET("/json", func(c *gin.Context) {data := map[string]string{"message": "Hello, JSON"}c.JSON(200, data)
})
5.3 常见的响应方法
- 纯文本响应:
c.String()
,适用于返回简单的文本。 - JSON 响应:
c.JSON()
,用于返回结构化的 JSON 数据。 - XML 响应:
c.XML()
,用于返回 XML 格式的数据。 - 文件响应:
c.File()
,用于返回文件内容。
6. 实践示例:创建用户管理 API
6.1 API 功能需求
我们将实现一个简单的用户管理 API,包含以下功能:
- GET /user/:id - 获取用户信息。
- POST /user - 创建新用户。
- PUT /user/:id - 更新用户信息。
- DELETE /user/:id - 删除用户。
6.2 完整代码
以下是完整的代码示例:
package mainimport ("github.com/gin-gonic/gin"
)type User struct {ID string `json:"id"`Name string `json:"name"`Age int `json:"age"`
}var users = make(map[string]User)func main() {r := gin.Default()r.GET("/user/:id", func(c *gin.Context) {id := c.Param("id")if user, exists := users[id]; exists {c.JSON(200, user)} else {c.JSON(404, gin.H{"error": "User not found"})}})r.POST("/user", func(c *gin.Context)var newUser Userif err := c.ShouldBindJSON(&newUser); err == nil {users[newUser.ID] = newUserc.JSON(201, gin.H{"message": "User created successfully", "user": newUser})} else {c.JSON(400, gin.H{"error": err.Error()})}
})r.PUT("/user/:id", func(c *gin.Context) {id := c.Param("id")if user, exists := users[id]; exists {var updatedUser Userif err := c.ShouldBindJSON(&updatedUser); err == nil {user.Name = updatedUser.Nameuser.Age = updatedUser.Ageusers[id] = userc.JSON(200, gin.H{"message": "User updated successfully", "user": user})} else {c.JSON(400, gin.H{"error": err.Error()})}} else {c.JSON(404, gin.H{"error": "User not found"})}
})r.DELETE("/user/:id", func(c *gin.Context) {id := c.Param("id")if _, exists := users[id]; exists {delete(users, id)c.JSON(200, gin.H{"message": "User deleted successfully"})} else {c.JSON(404, gin.H{"error": "User not found"})}
})r.Run(":8080")
}
6.3 代码解释
- 结构体定义:
User
结构体表示用户信息,包含ID
、Name
和Age
。 - 全局变量:
users
是一个用于存储用户信息的 map,键是用户的ID
。 - GET 请求:
r.GET("/user/:id")
获取特定用户的详细信息。 - POST 请求:
r.POST("/user")
使用c.ShouldBindJSON(&newUser)
解析 JSON 请求体数据。 - PUT 请求:
r.PUT("/user/:id")
更新现有用户的信息。 - DELETE 请求:
r.DELETE("/user/:id")
删除指定的用户。
6.4 运行与测试
- 启动服务器:运行
go run main.go
。 - 使用 Postman 或
curl
进行请求测试:- 创建用户:
POST /user
请求体为{ "id": "1", "name": "Alice", "age": 25 }
- 获取用户:
GET /user/1
- 更新用户:
PUT /user/1
请求体为{ "name": "Alice Updated", "age": 26 }
- 删除用户:
DELETE /user/1
- 创建用户:
7. 总结
在本篇博客中,我们详细介绍了 Gin 框架中路由与请求处理的基础知识,并通过代码示例展示了如何实现一个用户管理 API。希望这些内容能帮助你掌握 Gin 路由的基本操作。下一篇将进一步探讨 Gin 的中间件使用,带你构建更加灵活、强大的 API 服务。
相关文章:
【Golang】——Gin 框架中的路由与请求处理
文章目录 1. 路由基础1.1 什么是路由?1.2 Gin 中的路由概述 2. 创建简单路由2.1 基本路由定义2.2 不同请求方法的路由 3. 路由参数3.1 路径参数3.2 查询参数 4. 路由分组4.1 为什么使用路由分组?4.2 路由分组示例 5. 请求处理与响应5.1 Gin 中的 Context…...
nuxt3添加wowjs动效
1、安装wowjs pnpm i wowjs1.1.32、node_modules复制wowjs代码 路径/node_modules/wowjs/dist/wow.js。不知道路径则查看node_modules/wowjs/package.json里面的main选项 2.1、在public文件夹创建wowjs.js文件 /public/wowjs.js export default (callthis) > { // !!// 这是…...

我们是如何实现 TiDB Cloud Serverless 的 - 成本篇
作者: shiyuhang0 原文来源: https://tidb.net/blog/fbedeea4 背景 Serverless 数据库是云原生时代的产物,它提供全托管,按需付费,自动弹性的云数据库服务,让客户免于繁重的数据库运维工作。关于 Serve…...
PCL算法汇总
参考 【2024最新版】PCL点云处理算法汇总(C长期更新版)_pcl点云聚类c-CSDN博客...

sql注入之二次注入(sqlilabs-less24)
二阶注入(Second-Order Injection)是一种特殊的 SQL 注入攻击,通常发生在用户输入的数据首先被存储在数据库中,然后在后续的操作中被使用时,触发了注入漏洞。与传统的 SQL 注入(直接注入)不同&a…...
Android compose 软键盘 遮挡对话框中TextField 输入框
在AlertDialog对话框中含有TextField输入框时,弹出软件盘会遮挡输入框 解决1: 在AndroidManifest.xml的 MainActivity中添加如下 android:windowSoftInputMode"adjustResize" 然后AlertDialog 中的modify. modify.windowInsetsP…...

spring-data-elasticsearch 3.2.4 实现桶bucket排序去重,实现指定字段的聚合搜索
一、背景 es索引有一个文档CourseIndex,下面是示意: creatorIdgradesubjectnameno1002270英语听力课程一N00232DS91004380数学口算课程N00209DK71003480物理竞赛课程N00642XS21002280英语听力课程二N00432WS31002290英语听力课程三N002312DP5 在搜索的时候&#…...
【项目开发】分析六种常用软件架构
未经许可,不得转载。 文章目录 软件架构核心内容设计原则分层架构常见层次划分优缺点应用场景事件驱动架构核心组件优缺点应用场景微核架构核心概念优缺点应用场景微服务架构核心组件设计与实施优缺点应用场景云架构云架构模式优缺点应用场景软件架构 软件架构是指一个软件系…...
算法和程序的区别
算法(Algorithm)和程序(Program)是计算机科学中两个密切相关但不同的概念。让我们通过以下几个方面来比较它们: ### 1. 设计 vs 实现 - **算法设计(Algorithm Design)**: - **定…...

用指针遍历数组
#include<stdio.h> int main() {//定义一个二维数组int arr[3][4] {{1,2,3,4},{2,3,4,5},{3,4,5,6},};//获取二维数组的指针int (*p)[4] arr;//二维数组里存的是一维数组int[4]for (int i 0; i < 3; i){//遍历一维数组for (int j 0; j <4; j){printf("%d &…...

《Probing the 3D Awareness of Visual Foundation Models》论文解析——多视图一致性
一、论文简介 论文讨论了大规模预训练产生的视觉基础模型在处理任意图像时的强大能力,这些模型不仅能够完成训练任务,其中间表示还对其他视觉任务(如检测和分割)有用。研究者们提出了一个问题:这些模型是否能够表示物体…...
使用pip安装esp32的擦除、写入固件的esptool库
esptool库可以为esp32的开发板烧录新的固件,但是如果为了烧录固件就要装esp-idf软件包,甚至需要用make编译安装很久,实在太费时费力了! 好消息就是,esp提供了python的esptool库,这样只要使用pip安装上这个…...
传奇996_23——杀怪掉落,自动捡取,捡取动画
一、杀怪掉落 前置: 添加地图地图刷怪怪物掉落(术语叫爆率,掉落叫爆率,而且文档上叫爆率) 刷怪步骤:在\MirServer\Mir200\Envir\MonItems文件夹中建立以怪物名字为文件名的txt文件写法案例: …...
【030】基于51单片机甲醛检测报警器【Proteus仿真+Keil程序+报告+原理图】
☆、设计硬件组成:51单片机最小系统 ZE08-CH2O甲醛传感器AT24C02存储芯片LCD1602液晶显示按键设置蜂鸣器报警。 1、本设计采用STC89C52、AT89C52、AT89S52作为主控芯片; 2、采用ZE08-CH2O甲醛传感器采集环境中的甲醛浓度值,LCD1602实时显示…...

微信小程序:vant组件库安装步骤
前言:在微信小程序中引用vant组件报错,提示路径不存在,这很有可能是因为没有安装构建vant组件库导致。下面是我整理的安装vant组件库的步骤: 第一步:安装node.js(执行完第一步请重启小程序) 具体步骤请看链接:node.js…...
处理namespace问题:Namespace not specified for AGP 8.0.0
How do I fix ‘namespace not specified’ error in Android Studio? Namespace not specified for AGP 8.0.0 解决方案 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/androi…...

C++(Qt)软件调试---内存分析工具Heob(26)
C(Qt)软件调试—内存分析工具Heob(26) 文章目录 C(Qt)软件调试---内存分析工具Heob(26)[toc]1、概述🐜2、环境配置🪲3、功能说明4、使用Heob分析qt 程序内存泄漏🦧5、使用Heob检测qt 程序野指针…...

Redis五大基本类型——String字符串命令详解(命令用法详解+思维导图详解)
目录 一、String字符串类型介绍 二、常见命令 1、SET 2、GET 3、MGET 4、MSET 使用MGET 和 使用多次GET的区别 5、DEL 6、SETNX SET、SET NX和SET XX执行流程 7、INCR 8、INCRBY 9、DECR 10、DECYBY 11、INCRBYFLOAT 12、APPEND 13、GETRANGE 14、SETRANGE …...

Flutter中的Material Theme完全指南:从入门到实战
Flutter作为一款热门的跨平台开发框架,其UI组件库Material Design深受开发者喜爱。本文将深入探讨Flutter Material Theme的使用,包括如何借助Material Theme Builder创建符合产品需求的主题风格。通过多个场景和代码实例,让你轻松掌握这一工…...
Python 第三方库 PyQt5 的安装
目录 前言 PyQt5安装 不同操作系统PyQt5安装 一、Windows 系统 二、macOS 系统 三、Linux 系统(以 Ubuntu 为例) 安装 PyQt5 可能会遇到的问题 一、环境相关问题 二、依赖问题 三、网络问题 四、安装工具问题 五、运行时问题 六、环境配置问…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...