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

Gin 框架入门

Gin 框架入门

一、响应数据

JSON 响应

在 Web 开发中,JSON 是一种常用的数据交换格式。Gin 提供了简便的方法来响应 JSON 数据。

package mainimport ("github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/json", func(c *gin.Context) {c.JSON(200, gin.H{"message": "hello json",})})r.Run(":8080")
}

在上述代码中,通过 c.JSON() 方法,我们可以指定状态码和要响应的 JSON 数据,gin.H 是一个快捷的 map 类型,方便我们快速构建 JSON 响应内容。

文件响应

当需要响应文件时,Gin 也提供了简单易用的方法。

r.GET("/file", func(c *gin.Context) {c.File("./example.txt")
})

这里的 c.File() 方法直接将指定路径的文件响应给客户端。

HTML 响应

对于 HTML 页面的响应,Gin 同样有相应的方法。

r.LoadHTMLFiles("index.html") // 加载 HTML 模板文件r.GET("/html", func(c *gin.Context) {c.HTML(200, "index.html", gin.H{"title": "Gin HTML 响应示例",})
})

我们先通过 LoadHTMLFiles() 方法加载 HTML 模板文件,然后在路由处理函数中使用 c.HTML() 方法来渲染 HTML 页面,还可以将数据传递给模板进行动态展示。

重定向

重定向在 Web 开发中也经常用到,Gin 支持多种重定向方式。

r.GET("/redirect", func(c *gin.Context) {c.Redirect(302, "https://example.com")
})

上述代码实现了临时重定向,使用 c.Redirect() 方法指定重定向的状态码和目标 URL。

二、请求参数处理

查询参数

查询参数通常包含在 URL 的查询字符串中,我们可以通过 c.Query() 来获取单个查询参数,通过 c.DefaultQuery() 来获取带有默认值的查询参数。

r.GET("/query", func(c *gin.Context) {name := c.Query("name")age := c.DefaultQuery("age", "18")c.String(200, "name: %s, age: %s", name, age)
})

当我们访问 /query?name=John 时,输出为 name: John, age: 18

动态参数

动态参数可以定义在路由路径中,通过 :paramName 的形式指定,然后在处理函数中使用 c.Param() 获取。

r.GET("/user/:id", func(c *gin.Context) {id := c.Param("id")c.String(200, "User ID: %s", id)
})

当我们访问 /user/123 时,输出为 User ID: 123

表单参数

对于表单提交的数据,可以使用 c.PostForm() 来获取单个表单参数,使用 c.DefaultPostForm() 来获取带有默认值的表单参数。

r.POST("/form", func(c *gin.Context) {username := c.PostForm("username")password := c.DefaultPostForm("password", "123456")c.String(200, "Username: %s, Password: %s", username, password)
})

当表单提交包含 usernamepassword 字段时,就能正确获取并响应。

原始参数

对于原始的请求体数据,可以通过 c.Request.Body 来获取。

r.POST("/raw", func(c *gin.Context) {body, _ := ioutil.ReadAll(c.Request.Body)c.String(200, "Raw data: %s", body)
})

这样就能读取整个请求体的原始数据。

三、绑定参数

JSON 参数和 header 参数

Gin 支持使用绑定(binding)来将请求参数自动映射到结构体中。

type User struct {Username string `json:"username" binding:"required"`Password string `json:"password" binding:"required"`
}r.POST("/bind", func(c *gin.Context) {var user Userif err := c.ShouldBindJSON(&user); err != nil {c.JSON(400, gin.H{"error": err.Error()})return}c.JSON(200, gin.H{"username": user.Username,"password": user.Password,})// 获取 header 参数authHeader := c.Request.Header.Get("Authorization")c.JSON(200, gin.H{"auth_header": authHeader})
})

ShouldBindJSON() 方法中,会根据结构体中的标签(如 jsonbinding)来解析 JSON 参数并进行验证。通过 c.Request.Header.Get() 可以获取请求头中的参数。

绑定内置规则

Gin 提供了一些内置的验证规则,如 required 表示字段是必填的,minmax 可以限制字段的长度等。

type Product struct {Name  string `json:"name" binding:"required"`Price uint   `json:"price" binding:"required,gt=0"`
}

这里对 Price 字段设置了 requiredgt=0(大于 0)的验证规则。

绑定错误信息

当绑定验证不通过时,Gin 会返回相应的错误信息,我们可以在处理函数中捕获并返回给客户端。

if err := c.ShouldBindJSON(&user); err != nil {c.JSON(400, gin.H{"error": err.Error()})return
}

会将详细的错误信息返回给客户端,告知哪些字段验证不通过及其原因。

定义验证器

我们还可以自定义验证器来满足特定的验证需求。

import "github.com/go-playground/validator/v10"func init() {validate := validator.New()validate.RegisterValidation("mycustom", func(fl validator.FieldLevel) bool {return fl.Field().String() == "custom"})
}type Custom struct {Value string `json:"value" binding:"mycustom"`
}

RegisterValidation() 方法中注册自定义的验证规则,然后在结构体标签中使用该规则。

四、路由

Gin 的路由使用简单直观,通过 GETPOST 等方法来定义不同 HTTP 方法的路由。

r.GET("/index", indexHandler)
r.POST("/submit", submitHandler)

我们还可以使用通配符路由来匹配多个路径。

r.GET("/files/*filepath", func(c *gin.Context) {filepath := c.Param("filepath")c.String(200, "File path: %s", filepath)
})

当访问 /files/images/avatar.png 时,filepathimages/avatar.png

五、中间件

局部中间件

局部中间件只对特定的路由或路由组生效。

authorized := func() gin.HandlerFunc {return func(c *gin.Context) {// 中间件逻辑c.Next()}
}r.GET("/protected", authorized(), func(c *gin.Context) {c.String(200, "Protected resource")
})

这里 authorized() 中间件只对 /protected 路由生效。

全局中间件

全局中间件对所有路由都生效。

logger := func() gin.HandlerFunc {return func(c *gin.Context) {// 中间件逻辑c.Next()}
}r.Use(logger())

通过 r.Use() 方法添加全局中间件,它会在每个请求处理前执行,可用于日志记录、请求验证等通用功能。

相关文章:

  • 缓存(3):本地缓存作用 及 数据一致性 实现策略
  • 20242817-李臻-课下作业:Qt和Sqlite
  • MyBatis源码解读5(3.1、缓存简介)
  • 懒人美食帮SpringBoot订餐系统开发实现
  • MNIST DDP 分布式数据并行
  • Java泛型补充与理解
  • 虚幻引擎5-Unreal Engine笔记之常用核心类的继承关系
  • 【GESP真题解析】第 19 集 GESP 二级 2025 年 3 月编程题 1:等差矩阵
  • Scrapyd 详解:分布式爬虫部署与管理利器
  • C# 高效处理海量数据:解决嵌套并行的性能陷阱
  • 图片转ICO图标工具
  • 《Go小技巧易错点100例》第三十三篇
  • Flutter - UIKit开发相关指南 - 导航
  • 互联网大厂Java求职面试:电商商品推荐系统中的AI技术应用
  • 第31讲 循环缓冲区与命令解析
  • 【Tools】omnetpp5.6.2安装
  • 理解 Token 索引 vs 字符位置
  • DAY 17 训练
  • 【CTF】Linux Shell RCE绕过(bypass)技术总结
  • 低代码开发:开启软件开发的新篇章
  • 广州地铁十一号线赤沙车辆段工程高坠事故调查报告公布:1人重伤且漏报
  • “无锡景・江南韵”:中国评弹艺术在尼日利亚收获众多粉丝
  • 世贸组织欢迎中美经贸高层会谈取得积极成果
  • “饿了么”枣庄一站点两名连襟骑手先后猝死,软件显示生前3天每日工作超11小时
  • 印度最新发声:对所有敌对行动均予以反击和回应,不会升级冲突
  • 华泰柏瑞基金总经理韩勇因工作调整卸任,董事长贾波代为履职