Gin 中常见的参数接收

58 阅读3分钟

Gin框架是Go语言中一个非常流行的Web框架,它以高性能和良好的API设计而闻名。在使用Gin处理HTTP请求时,经常需要从客户端接收各种类型的参数(如查询字符串、表单数据或JSON等)。下面我将介绍几种常见的获取请求参数的方法:

路径参数(Path 参数)

适用于 /user/:id 这种 URL

r.GET("/user/:id", func(c *gin.Context) {
    id := c.Param("id")
    c.JSON(200, gin.H{"user_id": id})
})
// 匹配 /files/images/photo.jpg
r.GET("/files/*filepath", func(c *gin.Context) {
    filepath := c.Param("filepath") // 值为 /images/photo.jpg
    c.String(200, "File path: %s", filepath)
})
type UserURI struct {
    ID int `uri:"id" binding:"required"`
}

r.GET("/users/:id", func(c *gin.Context) {
    var uri UserURI
    if err := c.ShouldBindUri(&uri); err != nil {
        c.JSON(400, gin.H{"error": "Invalid ID"})
        return
    }
    c.JSON(200, gin.H{"user_id": uri.ID})
})

查询参数(Query 参数)

当你想从URL的查询部分 /hello?name=Gin

r.GET("/hello", func(c *gin.Context) {
    q := c.Query("q")
    name := c.DefaultQuery("name", "World") // 如果没传就默认 World
    c.JSON(200, gin.H{"message": "Hello " + name})
})
type TreeMenuReq struct {
   Type      int64  `form:"type" json:"type"` // 菜单类型
   QueryType string `form:"queryType" json:"queryType"`
}

var in TreeMenuReq
if err := ctx.ShouldBindQuery(&in); err != nil {
    ctx.JSON(400, gin.H{"error": err.Error()})
    return
}

表单参数(Post 表单)

对于HTML表单提交的数据,可以使用c.PostForm()方法来获取表单字段值。适用于表单格式请求(如 Content-Type: application/x-www-form-urlencoded)

r.POST("/login", func(c *gin.Context) {
    username := c.PostForm("username")
    password := c.PostForm("password")
    email := c.DefaultPostForm("email", "unknown@example.com")
    ...
})
type LoginForm struct {
    Username string `form:"username" binding:"required"`
    Password string `form:"password" binding:"required"`
}

func loginHandler(c *gin.Context) {
    var form LoginForm
    if err := c.ShouldBind(&form); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    // 处理登录逻辑
}

结构体绑定 JSON 参数

如果客户端发送的是JSON格式的数据,可以通过绑定到结构体来直接解析这些数据。

// 接收结构体
type RegisterRequest struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
    Username string `json:"username" binding:"required"`
    Password string `json:"password" binding:"required"`
}

// POST /register
func Register(c *gin.Context) {
    var req RegisterRequest

    // 自动解析 JSON 到结构体
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{
            "error": "参数错误:" + err.Error(),
        })
        return
    }

    // 返回欢迎消息
    c.JSON(http.StatusOK, gin.H{
        "message": "欢迎 " + req.Name,
        "age":     req.Age,
    })
}
{
    "name":"leolee",
    "age":12
}

常用校验规则

type SignUpForm struct {
    Email    string `json:"email" binding:"required,email"`
    Password string `json:"password" binding:"required,min=6,max=10"`
}
type RegisterRequest struct {
    Name string `json:"name" binding:"required"`      // 必填
    Age  int    `json:"age" binding:"gte=18,lte=120"` // 必填,18~120
}

// json是json的绑定方式
// form是url绑定方式,自动绑定也是这个字段。例;127.0.0.1:9090/query?name=张三&age=12&sex=男
// uri是另一种url的绑定方式uri/:name/:age/:sex。例;127.0.0.1:9090/uri/张三/12/男
type UserInfo struct {
	Name string `json:"name" form:"name" uri:"name"`
	Age  int    `json:"age" form:"age" uri:"age"`
	Sex  string `json:"sex" form:"sex" uri:"sex"`
}

  • ne:不等于参数值,例如ne=5;
  • gt:大于参数值,例如gt=5;
  • gte:大于等于参数值,例如gte=50;
  • lt:小于参数值,例如lt=50;
  • lte:小于等于参数值,例如lte=50;
  • oneof:只能是列举出的值其中一个,这些值必须是数值或字符串,以空格分隔,如果字符串中有空格,将字符串用单引号包围,例如oneof=male female。
  • eq:等于参数值,注意与len不同。对于字符串,eq约束字符串本身的值,而len约束字符串长度。例如* eq=10;
  • len:等于参数值,例如len=10;
  • max:小于等于参数值,例如max=10;
  • min:大于等于参数值,例如min=10

Fields约束

  • eqfield:定义字段间的相等约束,用于约束同一结构体中的字段。例如:eqfield=Password
  • eqcsfield:约束统一结构体中字段等于另一个字段(相对),确认密码时可以使用,例如:eqfiel=ConfirmPassword
  • nefield:用来约束两个字段是否相同,确认两种颜色是否一致时可以使用,例如:nefield=Color1
  • necsfield:约束两个字段是否相同(相对)