Gin 框架入门

发布于:2025-05-12 ⋅ 阅读:(11) ⋅ 点赞:(0)

Gin 框架入门

一、响应数据

JSON 响应

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

package main

import (
    "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 User
    if 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() 方法添加全局中间件,它会在每个请求处理前执行,可用于日志记录、请求验证等通用功能。


网站公告

今日签到

点亮在社区的每一天
去签到