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

【GO基础学习】gin的使用

文章目录

  • 模版使用流程
  • 参数传递
  • 路由分组
  • 数据解析和绑定
  • gin中间件


模版使用流程

package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {// 1.创建路由r := gin.Default()// 2.绑定路由规则,执行的函数// gin.Context,封装了request和responser.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "hello World!")})// 3.监听端口,默认在8080// Run("里面不指定端口号默认为8080") r.Run(":8000")
}

运行,访问:http://localhost:8000/

在这里插入图片描述
后面为了减少累赘代码,只展示路由规则部分代码编写,创建路由,以及端口监听部分代码保存相同。


参数传递

  1. API传参:可以通过Context的Param方法来获取API参数。
r.GET("/user/:name", func(c *gin.Context) {name := c.Param("name")c.String(http.StatusOK, "Hello "+name+"!")})

在这里插入图片描述

r.GET("/user/:name/*action", func(c *gin.Context) {name := c.Param("name")action := c.Param("action")c.String(http.StatusOK, "Hello "+name+"!"+"Action "+action)})

在这里插入图片描述

*action 表示一个通配路径参数,可以匹配 URL 剩余部分的路径,并且会包含匹配部分的斜杠 /

  1. URL传参:URL参数可以通过DefaultQuery()Query()方法获取,DefaultQuery()若参数不存在,返回默认值,Query()若不存在,返回空串。

DefaultQuery默认值只支持string类型:

func (c *Context) DefaultQuery(key, defaultValue string) string {if value, ok := c.GetQuery(key); ok {return value}return defaultValue
}
r.GET("/user", func(c *gin.Context) {name := c.DefaultQuery("name", "Test")ageStr := c.DefaultQuery("age", "18")age, err := strconv.Atoi(ageStr)if err != nil {c.String(http.StatusBadRequest, "Invalid age")return}c.String(http.StatusOK, fmt.Sprintf("%s is %d years old", name, age))})

在这里插入图片描述

  1. 表单传值
<form action="http://localhost:8000/form" method="post" action="application/x-www-form-urlencoded">用户名:<input type="text" name="username" placeholder="请输入你的用户名">  <br>&nbsp;&nbsp;&nbsp;码:<input type="password" name="userpassword" placeholder="请输入你的密码">  <br><input type="submit" value="提交"></form>
r.POST("/form", func(c *gin.Context) {types := c.DefaultPostForm("type", "post")username := c.PostForm("username")password := c.PostForm("userpassword")c.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s", username, password, types))})
  1. 文件上传

单个文件:

<form action="http://localhost:8000/upload" method="post" enctype="multipart/form-data">上传文件:<input type="file" name="file" ><input type="submit" value="提交"></form>
// 限制上传文件大小 (10 MiB)r.MaxMultipartMemory = 10 << 20 // 10 MiB// 文件上传路由r.POST("/upload", func(c *gin.Context) {// 获取文件file, err := c.FormFile("file")if err != nil {c.String(http.StatusBadRequest, "File upload error: %s", err.Error())return}// 检查文件类型 (仅允许 image/png)mimeType := file.Header.Get("Content-Type")if mimeType != "image/png" {c.String(http.StatusBadRequest, "Invalid file type: %s. Only PNG images are allowed.", mimeType)return}// 保存文件到目标路径dst := filepath.Join("./uploads", file.Filename)if err := c.SaveUploadedFile(file, dst); err != nil {c.String(http.StatusInternalServerError, "Could not save file: %s", err.Error())return}c.String(http.StatusOK, "File uploaded successfully: %s", file.Filename)})

多个文件:

// 限制上传文件大小 (10 MiB)r.MaxMultipartMemory = 10 << 20 // 10 MiB// 多文件上传路由r.POST("/upload/multiple", func(c *gin.Context) {// 获取表单文件 (key 为 "files")form, err := c.MultipartForm()if err != nil {c.String(http.StatusBadRequest, "Form error: %s", err.Error())return}files := form.File["files"] // 获取多个文件for _, file := range files {// 检查文件类型 (仅允许 image/png)mimeType := file.Header.Get("Content-Type")if mimeType != "image/png" {c.String(http.StatusBadRequest, "Invalid file type: %s for file: %s. Only PNG images are allowed.", mimeType, file.Filename)return}// 保存文件到目标路径dst := filepath.Join("./uploads", file.Filename)if err := c.SaveUploadedFile(file, dst); err != nil {c.String(http.StatusInternalServerError, "Could not save file: %s. Error: %s", file.Filename, err.Error())return}fmt.Printf("Uploaded file: %s\n", file.Filename)}c.String(http.StatusOK, "All files uploaded successfully")})

路由分组

在 Gin 框架中,路由分组(Route Group)是用于组织和管理路由的功能。通过路由分组,可以为一组路由添加公共的前缀、中间件或配置,从而提高代码的可读性和可维护性。

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {// 1.创建路由r := gin.Default()// 2.绑定路由规则,执行的函数// gin.Context,封装了request和response// 用户路由组userGroup := r.Group("/user"){userGroup.GET("/login", login)userGroup.GET("/settings", func(c *gin.Context) {c.JSON(200, gin.H{"message": "User Settings"})})}// 管理员路由组adminGroup := r.Group("/admin"){adminGroup.GET("/dashboard", func(c *gin.Context) {c.JSON(200, gin.H{"message": "Admin Dashboard"})})adminGroup.GET("/reports", func(c *gin.Context) {c.JSON(200, gin.H{"message": "Admin Reports"})})}// 404r.NoRoute(func(c *gin.Context) {c.String(http.StatusNotFound, "404 not found !!!!")})// 3.监听端口,默认在8080// Run("里面不指定端口号默认为8080")r.Run(":8000")
}func login(c *gin.Context) {name := c.DefaultQuery("name", "jack")c.JSON(200, gin.H{"name": name})
}

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


数据解析和绑定

  1. JSON数据解析和绑定的基本步骤

(1) 定义结构体

定义一个与 JSON 数据格式匹配的 Go 结构体。

(2) 使用 c.BindJSONc.ShouldBindJSON

  • c.BindJSON 会在绑定失败时返回错误并终止请求。
  • c.ShouldBindJSON 返回错误但不会中断后续处理,适合灵活的错误处理场景。

(3) 使用结构体处理数据

通过绑定的结构体直接访问解析后的字段。

package mainimport ("net/http""github.com/gin-gonic/gin"
)type User struct {Name  string `json:"name" binding:"required"` // 必填字段Age   int    `json:"age" binding:"required"`  // 必填字段Email string `json:"email"`                  // 可选字段
}func main() {r := gin.Default()r.POST("/user", func(c *gin.Context) {var user Userif err := c.ShouldBindJSON(&user); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"message": "User data received","user":    user,})})r.Run(":8080")
}

在这里插入图片描述

Gin 提供了 binding 标签,用于对字段进行验证。支持多种验证规则。

type User struct {Name  string `json:"name" binding:"required,min=3"` // 必填,最小长度 3Age   int    `json:"age" binding:"required,gte=1"`  // 必填,必须大于等于 1Email string `json:"email" binding:"required,email"` // 必填,必须是合法邮箱
}
验证规则含义
required必须提供该字段
min字符串或切片的最小长度
max字符串或切片的最大长度
gte数字或时间的值必须大于等于指定值
lte数字或时间的值必须小于等于指定值
email必须是有效的邮箱地址

  1. 表单数据:
    为字段添加多种绑定方式的标签,例如 jsonform 标签。

Gin 会根据 Content-Type 自动选择适合的绑定方式:

  • 如果是 application/json,则绑定 JSON 数据。
  • 如果是 application/x-www-form-urlencodedmultipart/form-data,则绑定表单数据。
type User struct {Name  string `json:"name" form:"name" binding:"required"` // 必填字段Age   int    `json:"age" form:"age" binding:"required,gte=0"`Email string `json:"email" form:"email"`
}
  1. URI数据

通过 c.Param 获取路径参数的值

package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/user/:id", func(c *gin.Context) {id := c.Param("id") // 提取路径参数c.JSON(http.StatusOK, gin.H{"user_id": id,})})r.Run(":8080")
}

Gin 提供了 ShouldBindUri 方法,可以将路径参数直接绑定到结构体中,方便处理和验证。

package mainimport ("net/http""github.com/gin-gonic/gin"
)type UserRequest struct {ID string `uri:"id" binding:"required"` // 使用 `uri` 标签定义路径参数
}func main() {r := gin.Default()r.GET("/user/:id", func(c *gin.Context) {var req UserRequest// 将路径参数绑定到结构体if err := c.ShouldBindUri(&req); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"user_id": req.ID,})})r.Run(":8080")
}
  1. 路径参数可以和查询参数或表单参数结合使用。Gin 支持同时解析这些参数。
package mainimport ("net/http""github.com/gin-gonic/gin"
)type UserRequest struct {ID   string `uri:"id" binding:"required"`  // 路径参数Name string `form:"name"`                 // 查询参数或表单参数
}func main() {r := gin.Default()r.GET("/user/:id", func(c *gin.Context) {var req UserRequest// 绑定路径参数if err := c.ShouldBindUri(&req); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}// 绑定查询参数if err := c.ShouldBindQuery(&req); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"user_id": req.ID,"name":    req.Name,})})r.Run(":8080")
}
GET /user/123?name=Alice

gin中间件

在 Gin 中,中间件是一个可以插入到请求处理流程中的函数,用于实现请求前后的通用逻辑。例如,认证、日志记录、跨域处理等都可以通过中间件实现。

  1. 中间件定义
func(c *gin.Context) {// 执行逻辑c.Next() // 调用后续处理函数// 执行逻辑
}

c.Next():调用下一个中间件或处理程序。
c.Abort():停止执行后续的中间件和处理程序。

  1. 全局中间件

全局中间件会应用到所有路由,使用 r.Use() 注册。

package mainimport ("fmt""github.com/gin-gonic/gin"
)func Logger() gin.HandlerFunc {return func(c *gin.Context) {// 请求前逻辑fmt.Println("Request URL:", c.Request.URL.Path)c.Next() // 执行后续处理// 请求后逻辑fmt.Println("Response Status:", c.Writer.Status())}
}func main() {r := gin.Default()// 注册全局中间件r.Use(Logger())r.GET("/ping", func(c *gin.Context) {fmt.Println("=======11111111")c.String(200, "pong")})r.Run(":8080")
}

控制台输出:

Request URL: /ping
=======11111111
Response Status: 200

流程:中间件逻辑=》遇到next方法后,执行路由func=》中间件后面的逻辑。

  1. 局部中间件

局部中间件只应用于特定路由或路由组。

package mainimport ("github.com/gin-gonic/gin"
)func AuthRequired() gin.HandlerFunc {return func(c *gin.Context) {token := c.GetHeader("Authorization")if token != "valid-token" {c.AbortWithStatusJSON(401, gin.H{"error": "unauthorized"})return}c.Next()}
}func main() {r := gin.Default()// 局部中间件r.GET("/secure", AuthRequired(), func(c *gin.Context) {c.JSON(200, gin.H{"message": "Authorized"})})r.Run(":8080")
}

相关文章:

【GO基础学习】gin的使用

文章目录 模版使用流程参数传递路由分组数据解析和绑定gin中间件 模版使用流程 package mainimport ("net/http""github.com/gin-gonic/gin" )func main() {// 1.创建路由r : gin.Default()// 2.绑定路由规则&#xff0c;执行的函数// gin.Context&#x…...

网卡状态变更,virtio-net检测

实现方案&#xff1a; 现在在amp模式下linux端有个真实的物理网卡eth0&#xff0c;有一个虚拟网卡virtio-net0后端&#xff0c;此时需要一种机制&#xff0c;将真实物理网卡的状态发送rtos的virtio-net0前端。这里使用register_netdevice_notifier机制&#xff0c;每个virtio-n…...

中华人民共和国保守国家秘密法

中华人民共和国保守国家秘密法 &#xff08;1988年9月5日第七届全国人民代表大会常务委员会第三次会议通过 2010年4月29日第十一届全国人民代表大会常务委员会第十四次会议第一次修订 2024年2月27日第十四届全国人民代表大会常务委员会第八次会议第二次修订&#xff09; 目…...

ELK日志收集系统部署

1、 ElasticSearch部署 Elastic — 搜索 AI 公司 | Elastic 系统类型&#xff1a;Centos7.4 节点IP&#xff1a;172.16.246.234 软件版本&#xff1a;jdk-8u191-linux-x64.tar.gz、elasticsearch-6.5.4.tar.gz 示例节点&#xff1a;172.16.246.234 1、安装配置jdk8 ES运行依…...

3D线上艺术展:艺术与技术的完美融合

随着数字技术的飞速发展&#xff0c;未来的艺术展览正逐步迈向线上线下融合的新阶段。其中&#xff0c;3D线上展览以其独特的魅力&#xff0c;成为线下展览的延伸与拓展&#xff0c;为艺术爱好者们开辟了全新的观赏途径。 对于艺术家和策展人而言&#xff0c;3D线上展览不仅打…...

TiDB 的MPP架构概述

MPP架构介绍&#xff1a; 如图&#xff0c;TiDB Server 作为协调者&#xff0c;首先 TiDB Server 会把每个TiFlash 拥有的region 会在TiFlash上做交换&#xff0c;让表连接在一个TiFlash上。另外 TiFlash会作为计算节点&#xff0c;每个TiFlash都负责数据交换&#xff0c;表连接…...

Leetcode 10-正则表达式匹配/ 剑指 Offer 19. 正则表达式匹配

给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 ‘*’ 匹配零个或多个前面的那一个元素 所谓匹配&#xff0c;是要涵盖 整个 字符串 s 的&#xff0c;而不是部分字符串。 题解 字符串匹配多…...

FFmpeg 编码和解码

文章目录 音频格式AACADIF音频数据交换格式ADTS音频数据传输流 音频解码音频编码 视频格式H264GOP图像组I帧&#xff0c;P帧&#xff0c;B帧H264压缩技术H264压缩级别H264视频级别H264码流结构SPSPPS 解码视频编码视频 音频格式 AAC AAC全称 Advanced Audio Coding&#xff0…...

kali当中web扫描工具的用法

1. cadaver 用途&#xff1a;用于与WebDAV服务器交互&#xff0c;可进行文件上传、下载、目录浏览等操作。使用方法 连接到WebDAV服务器&#xff1a;cadaver <WebDAV服务器地址>&#xff0c;例如cadaver https://example.com/dav&#xff0c;然后按提示输入用户名和密码…...

深度剖析 Android Animation 框架

深度剖析 Android Animation 框架 目录 引言Android Animation 框架概述架构设计 3.1 核心类与接口3.2 动画类型3.3 动画执行流程使用指南 4.1 属性动画4.2 视图动画4.3 过渡动画设计模式 5.1 策略模式5.2 观察者模式5.3 工厂模式核心逻辑 6.1 动画插值器6.2 动画估值器6.3 动…...

泰山派GPIO子系统驱动---亮灯

本人linux驱动小白&#xff0c;文章基于B站up主 李Sir______ 视频内容记录&#xff0c;做笔记用。如有错误欢迎指正。本文将以开发板第40引脚GPIO3_B4作为LED灯珠的控制引脚&#xff0c;高电平灯亮&#xff0c;低电平灯灭。 杂话 在linux内核中&#xff0c;芯片厂商已经把所有…...

【C#特性整理】C#特性及语法基础

1. C#特性 1.1 统一的类型系统 C#中, 所有类型都共享一个公共的基类型. 例如&#xff0c;任何类型的实例都可以通过调用ToString方法将自身转换为一个字符串 1.2 类和接口 接口: 用于将标准与实现隔离, 仅仅定义行为,不做实现. 1.3 属性、方法、事件 属性: 封装了一部分对…...

Presence:Colyseus用于管理实时分布式数据的工具

Colyseus Presence 详细介绍 Presence 是 Colyseus 中用于管理实时分布式数据的一种工具。它主要用于在多房间、多服务器或分布式部署中实现玩家的实时在线状态、数据共享和通信。Presence 提供了一套简单的 API 来处理诸如在线玩家跟踪、分布式数据存储和发布/订阅模式等功能…...

Ubuntu 搭建SVN服务

目录 ​ 1、安装SVN服务端 2、创建SVN版本库 3、修改SVN配置svnserve.conf 3.1 配置文件介绍 3.2 svnserve.conf配置 3.3 authz配置设置用户读写权限 3.4 passwd配置 用户名密码 4、启动SVN服务 4.1 配置开机启动 1、安装SVN服务端 sudo apt-get install subversion…...

HTML速查

HTML 基本文档 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>文档标题</title></head><body>可见文本...</body> </html>基本标签&#xff08;Basic Tags&#xff09; <h1>最大的…...

day-102 二进制矩阵中的最短路径

思路 BFS 解题过程 从起点依次向八个方向尝试&#xff08;之后也一样&#xff09;&#xff0c;如果某个位置在矩阵内且值为0且没有访问过&#xff0c;将其添加到一个队列中&#xff0c;依次类推&#xff0c;直到到达出口 Code class Solution {public int shortestPathBinar…...

SQL Server大批量数据插入

数据库连接及相关操作 public class DataBase {/*** 驱动*/private static final String DRIVER PropertiesUtil.getString("spring.datasource.driver-class-name");/*** 数据库地址*/private static final String URL PropertiesUtil.getString("spring.da…...

在 Ubuntu 下通过 Docker 部署 Caddy 服务器

嘿&#xff0c;伙伴们&#xff01;今天我们来聊聊如何在 Ubuntu 系统下通过 Docker 部署 Caddy 服务器。Caddy 是一个现代的 Web 服务器&#xff0c;支持自动 HTTPS&#xff0c;简单易用&#xff0c;特别适合快速搭建网站。而 Docker 则是一个让你可以隔离和管理应用的神器。结…...

ZooKeeper注册中心实现

具体步骤 安装ZooKeeper&#xff08;启动端口占用&#xff0c;2181&#xff1a;客户端&#xff0c;8080&#xff1a;管理端&#xff09;引入客户端依赖实现注册中心接口SPI补充ZooKeeper注册中心 引入依赖 <!-- zookeeper --> <dependency><groupId>org.a…...

数仓建模:如何进行实体建模?

目录 1 如何进行实体建模? 业务建模 领域建模 逻辑建模 2 实体建模具体步骤 需求分析...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

验证redis数据结构

一、功能验证 1.验证redis的数据结构&#xff08;如字符串、列表、哈希、集合、有序集合等&#xff09;是否按照预期工作。 2、常见的数据结构验证方法&#xff1a; ①字符串&#xff08;string&#xff09; 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...