常用函数
Gin 框架中,gin.H
是一个高频使用的工具类型,其核心作用是简化 JSON 数据的构造和响应。
语法定义
gin.H
是 map[string]interface{}
的类型别名,源码中直接声明为:
type H map[string]interface{}
-
功能定位:用于快速构建键值对形式的动态数据结构
-
示例 :
typescriptr.GET("/user", func(c *gin.Context) { c.JSON(200, gin.H{ "profile": gin.H{ "name": "张三", "age": 25, "active": true, }, "roles": []string{"admin", "editor"}, }) }) //输出 { "profile": {"name": "张三", "age": 25, "active": true}, "roles": ["admin", "editor"] }
Gin 框架中,
c.JSON
和c.String
是用于向客户端返回 HTTP 响应的核心方法
c.String()
:返回纯文本或 HTML 内容
go
r.GET("/hello", func(c *gin.Context) {
name := c.Query("name")
c.String(200, "Welcome, %s!", name)
})
c.JSON()
:返回结构化 JSON 数据
go
//使用 gin.H 快速构建键值对
c.JSON(200, gin.H{
"status": "success",
"message": "Data loaded",
})
//范湖结构体
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
r.GET("/user", func(c *gin.Context) {
user := User{Name: "Bob", Age: 30}
c.JSON(200, user)
})
c.Redirect()
- 实现客户端 URL 跳转,适用于站外跳转或永久/临时资源迁移
go
//301 Moved Permanently
//资源永久迁移,搜索引擎更新索引:
c.Redirect(http.StatusMovedPermanently, "https://new-domain.com")
//302 Found(默认)
//资源临时迁移,浏览器下次仍访问原 URL:
c.Redirect(http.StatusFound, "/temporary-path")
//代码示例:
r.GET("/old", func(c *gin.Context) {
// 永久重定向到外部站点
c.Redirect(301, "https://example.com")
})
服务器内部跳转,客户端 URL 不变
javascript
//转发后的路由仍会经过全局中间件处理
//浏览器地址栏 URL 不变,但实际处理逻辑由新路由完成
r.GET("/a", func(c *gin.Context) {
// 内部转发到 /b 路由
c.Request.URL.Path = "/b"
r.HandleContext(c)
})
r.GET("/b", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "内部重定向成功"})
})
获取浏览器传递参数
URL 路径参数(动态路由参数)
适用于形如 /user/:id
的路由:
go
// 定义路由
r.GET("/user/:id", func(c *gin.Context) {{
id := c.Param("id") // 获取路径参数(如 /user/123)
}})
支持多级路径(如 /book/:category/:title
)
GET 参数(URL 查询参数)
通过 URL 的 ?
后传递的参数(如 /user?id=123
),使用以下方法获取:
-
c.Query("key")
获取单个参数,若不存在返回空字符串:
id := c.Query("id") // 获取 id=123
-
c.DefaultQuery("key", "default")
参数不存在时返回默认值:
page := c.DefaultQuery("page", "1") // 默认第一页
-
c.GetQuery("key")
返回参数值和是否存在标识:
if name, exists := c.GetQuery("name"); exists {{ // 处理 name 参数 }}
-
c.QueryArray("key")
获取多值参数(如
?ids=1&ids=2
):ids := c.QueryArray("ids") // []string{{"1", "2"}}
POST 参数(表单/Form 数据)
适用于
application/x-www-form-urlencoded
或multipart/form-data
格式的请求体: -
c.PostForm("key")
获取表单字段值:
username := c.PostForm("username")
-
c.DefaultPostForm("key", "default")
字段不存在时返回默认值:
age := c.DefaultPostForm("age", "18")
-
c.PostFormArray("key")
获取多值表单字段(如复选框):
hobbies := c.PostFormArray("hobbies")
-
c.PostFormMap("key")
解析表单字段为 Map(如
user[name]=John
):userMap := c.PostFormMap("user")
JSON 参数(请求体中的 JSON 数据)
适用于
application/json
格式的请求体: -
绑定到结构体(推荐)
定义结构体并使用
ShouldBindJSON
:gotype User struct {{ Name string `json:"name"` Age int `json:"age"` }} var user User if err := c.ShouldBindJSON(&user); err == nil {{ fmt.Println(user.Name) // 直接访问字段 }}
-
原始数据读取
手动读取请求体并解析:
kotlindata, _ := c.GetRawData() // 获取原始字节流 json.Unmarshal(data, &user)
注意事项:需处理可能的 JSON 解析错误
Gin设置 Cookie
go
c.SetCookie(
"user_id", // Cookie 名称
"123", // 值
3600, // 过期时间(秒)
"/", // 生效路径
"example.com", // 域名(可选)
false, // 仅 HTTPS 传输(Secure)
true, // 禁止 JS 访问(HttpOnly)
)
//关键参数说明:
//Secure=true:仅通过 HTTPS 传输,防止中间人窃取5。
//HttpOnly=true:禁止 JavaScript 访问,预防 XSS 攻击
userID, _ := c.Cookie("user_id") // 获取指定 Cookie
allCookies := c.Request.Cookies() // 获取所有 Cookie
c.SetCookie("user_id", "", -1, "/", "", false, true)//设置过期时间为负数即可删除:
Gin设置 Session
依赖第三方库 gin-contrib/sessions
arduino
go get github.com/gin-contrib/sessions
基于 Cookie 的 Session 存储
特点
- 会话数据直接存储在客户端的 cookie 中
- 无需服务器存储空间
- 适合小型会话数据(cookie 有大小限制 根据浏览器决定.一般不超过4KB)
- 数据经过加密,但安全性相对较低
go
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
"time"
)
func main() {
r := gin.Default()
// 创建一个基于 Cookie 的会话存储
store := cookie.NewStore([]byte("secret"))
// 设置会话的最大存活时间为 10 分钟
store.Options(sessions.Options{
MaxAge: int(10 * time.Minute.Seconds()),
})
r.Use(sessions.Sessions("mysession", store))
// 设置会话
r.GET("/set", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("user", "John Doe")
session.Save()
c.JSON(200, gin.H{"message": "Session set successfully"})
})
// 获取会话
r.GET("/get", func(c *gin.Context) {
session := sessions.Default(c)
user := session.Get("user")
c.JSON(200, gin.H{"user": user})
})
// 删除会话
r.GET("/delete", func(c *gin.Context) {
session := sessions.Default(c)
session.Delete("user")
session.Save()
c.JSON(200, gin.H{"message": "Session deleted successfully"})
})
r.Run(":8080")
}
基于服务器内存的 Session 存储
特点
- 会话数据存储在服务器内存中
- 访问速度快
- 服务器重启后会话数据会丢失
- 不适合分布式环境
实现代码
go
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/memstore"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 创建基于内存的存储
store := memstore.NewStore([]byte("secret-key"))
// 使用 sessions 中间件
r.Use(sessions.Sessions("mysession", store))
r.GET("/set", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("key", "value")
session.Save()
c.String(200, "Session saved")
})
r.GET("/get", func(c *gin.Context) {
session := sessions.Default(c)
value := session.Get("key")
c.String(200, "Session value: %v", value)
})
r.Run(":8080")
}
注意事项
- 适用于单机部署
- 内存占用会随着会话数量增加而增加
- 需要定期清理过期会话
基于数据库的 Session 存储
特点
- 会话数据存储在数据库中
- 支持持久化,服务器重启不会丢失
- 适合分布式环境
- 访问速度比内存存储慢
支持的数据存储
gin-contrib/sessions
支持多种数据库后端:
- Redis (推荐)
- MongoDB
- PostgreSQL
- MySQL
- 其他关系型数据库
Redis 实现示例
go
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/redis"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 创建基于 Redis 的存储
store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret-key"))
// 使用 sessions 中间件
r.Use(sessions.Sessions("mysession", store))
r.GET("/set", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("key", "value")
session.Save()
c.String(200, "Session saved")
})
r.GET("/get", func(c *gin.Context) {
session := sessions.Default(c)
value := session.Get("key")
c.String(200, "Session value: %v", value)
})
r.Run(":8080")
}
关系型数据库实现示例
go
package main
import (
"database/sql"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/postgres"
"github.com/gin-gonic/gin"
_ "github.com/lib/pq"
)
func main() {
r := gin.Default()
// 初始化数据库连接
db, err := sql.Open("postgres", "user=postgres dbname=test sslmode=disable")
if err != nil {
panic(err)
}
// 创建基于 PostgreSQL 的存储
store, err := postgres.NewStore(db, []byte("secret-key"))
if err != nil {
panic(err)
}
// 使用 sessions 中间件
r.Use(sessions.Sessions("mysession", store))
r.GET("/set", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("key", "value")
session.Save()
c.String(200, "Session saved")
})
r.GET("/get", func(c *gin.Context) {
session := sessions.Default(c)
value := session.Get("key")
c.String(200, "Session value: %v", value)
})
r.Run(":8080")
}
5. 三种存储方式的比较
特性 | Cookie 存储 | 内存存储 | 数据库存储 |
---|---|---|---|
存储位置 | 客户端 | 服务器内存 | 数据库 |
持久性 | 是 | 否 | 是 |
分布式支持 | 是 | 否 | 是 |
性能 | 最高 | 高 | 中等 |
数据大小限制 | 有(约4KB) | 无 | 无 |
安全性 | 较低 | 高 | 高 |
适用场景 | 小型非敏感数据 | 单机应用 | 分布式/生产环境 |
高级配置选项
所有存储类型都支持一些共同的配置选项:
go
store.Options(sessions.Options{
Path: "/", // cookie 路径
Domain: "", // cookie 域名
MaxAge: 86400 * 7, // 有效期(秒)
Secure: true, // 仅 HTTPS
HttpOnly: true, // 防止 XSS
SameSite: http.SameSiteLaxMode, // CSRF 防护
})