go框架gin(中)

常用函数

Gin 框架中,gin.H 是一个高频使用的工具类型,其核心作用是简化 JSON 数据的构造和响应。

语法定义
gin.Hmap[string]interface{} 的类型别名,源码中直接声明为:

type H map[string]interface{}

  • 功能定位:用于快速构建键值对形式的动态数据结构

  • 示例 :

    typescript 复制代码
    r.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.JSONc.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),使用以下方法获取:

  1. c.Query("key")

    获取单个参数,若不存在返回空字符串:

    id := c.Query("id") // 获取 id=123

  2. c.DefaultQuery("key", "default")

    参数不存在时返回默认值:

    page := c.DefaultQuery("page", "1") // 默认第一页

  3. c.GetQuery("key")

    返回参数值和是否存在标识:

    if name, exists := c.GetQuery("name"); exists {{ // 处理 name 参数 }}

  4. c.QueryArray("key")

    获取多值参数(如 ?ids=1&ids=2):

    ids := c.QueryArray("ids") // []string{{"1", "2"}}

    POST 参数(表单/Form 数据)

    适用于 application/x-www-form-urlencodedmultipart/form-data 格式的请求体:

  5. c.PostForm("key")

    获取表单字段值:

    username := c.PostForm("username")

  6. c.DefaultPostForm("key", "default")

    字段不存在时返回默认值:

    age := c.DefaultPostForm("age", "18")

  7. c.PostFormArray("key")

    获取多值表单字段(如复选框):

    hobbies := c.PostFormArray("hobbies")

  8. c.PostFormMap("key")

    解析表单字段为 Map(如 user[name]=John):

    userMap := c.PostFormMap("user")

    JSON 参数(请求体中的 JSON 数据)

    适用于 application/json 格式的请求体:

  9. 绑定到结构体(推荐)

    定义结构体并使用 ShouldBindJSON

    go 复制代码
    type User struct {{
        Name string `json:"name"`
        Age  int    `json:"age"`
    }}
    var user User 
    if err := c.ShouldBindJSON(&user); err == nil {{
        fmt.Println(user.Name) // 直接访问字段 
    }}
  10. 原始数据读取

    手动读取请求体并解析:

    kotlin 复制代码
    data, _ := c.GetRawData() // 获取原始字节流
    json.Unmarshal(data, &user)

    注意事项:需处理可能的 JSON 解析错误

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 中
  • 无需服务器存储空间
  • 适合小型会话数据(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 防护
})

相关推荐
郭京京2 小时前
go框架gin(下)
后端·go
林树的编程频道2 小时前
单例模式的推导
后端
就是帅我不改2 小时前
揭秘Netty高性能HTTP客户端:NIO编程的艺术与实践
后端·面试·github
Ray662 小时前
SugLucene索引构建
后端
舒一笑2 小时前
Saga分布式事务框架执行逻辑
后端·程序员·设计
Emma歌小白3 小时前
完整后台模块模板
后端
得物技术3 小时前
MySQL单表为何别超2000万行?揭秘B+树与16KB页的生死博弈|得物技术
数据库·后端·mysql
Emma歌小白3 小时前
配套后端(Node.js + Express + SQLite)
后端
isysc13 小时前
面了一个校招生,竟然说我是老古董
java·后端·面试