调用 c.ShouldBind 方法时:
如果是 GET 请求,只使用 Form 绑定引擎(query)。
如果是 POST 请求,首先检查 content-type 是否为 JSON 或 XML,然后再使用 Form(form-data)。

示例代码:

package main

import (
	"log"
	"time"

	"github.com/gin-gonic/gin"
)

type Person struct {
	Name     string    `form:"name"`
	Address  string    `form:"address"`
	Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
}

func main() {
	route := gin.Default()
	route.Any("/testing", startPage)
	route.Run(":8085")
}

func startPage(c *gin.Context) {
	var person Person

	// 如果是 `GET` 请求,只使用 `Form` 绑定引擎(`query`)。
	// 如果是 `POST` 请求,首先检查 `content-type` 是否为 `JSON` 或 `XML`,然后再使用 `Form`(`form-data`)。
	// 查看更多:https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
	if err := c.ShouldBind(&person); err == nil {
		log.Println(person.Name)
		log.Println(person.Address)
		log.Println(person.Birthday)
	} else {
		log.Println("error: " + err.Error())
	}

	c.String(200, "Success")
}

路由中的 /testing 被定义为 Any,接受任意类型的 HTTP 请求方法。

测试 GET 请求:

$ curl -X GET 'http://localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15'

测试 formData 格式的 POST 请求:

$ curl -X POST 'http://localhost:8085/testing' -d 'name=michael&address=shenzhen&birthday=1989-05-02'

测试 JSON 格式的 POST 请求(字段名与结构体一致):

$ curl -X POST 'http://localhost:8085/testing' \
  -d '{"Name":"michael", "Address":"shenzhen", "Birthday":"2011-09-21T13:26:50Z"}' \
  -H 'Content-Type:application/json'

测试 JSON 格式的 POST 请求(字段名小写):

$ curl -X POST 'http://localhost:8085/testing' \
  -d '{"name":"michael", "address":"shenzhen", "birthday":"2011-09-21T13:26:50Z"}' \
  -H 'Content-Type:application/json'

测试 XML 格式的 POST 请求(字段名与结构体一致):

$ curl -X POST 'http://localhost:8085/testing' \
  -d '<root><Name>myname</Name><Address>xyz</Address><Birthday>2020-03-15T06:51:28Z</Birthday></root>' \
  -H 'Content-Type:application/xml'

测试 XML 格式的 POST 请求(字段名大小写不一致,无法解析):

$ curl -X POST 'http://localhost:8085/testing' \
  -d '<root><name>myname</name><address>xyz</address><birthday>2020-03-15T06:51:28Z</birthday></root>' \
  -H 'Content-Type:application/xml'

特别提示:

  • 结构体中的 Birthday 字段要求 UTC 格式,当请求方式为 GET 或 formData 格式的 POST 时,字段值可以是短日期;当请求格式为 JSON 或 XML 时,Birthday 字段值要求是长日期格式。
  • 结构体 Person 各字段的 tag 只定义了 form 表单映射名称,即执行 c.ShouldBind 时 GET 请求的 queryString 或 POST 请求的 formData 要有同名字段(示例中全为小写)。
  • 结构体 Person 没有定义 JSON 字段映射名称 `json:"xxx"` ,发起 JSON 格式请求时,JSON 中的字段名即使是小写,也可以被正确解析。
  • 结构体 Person 没有定义 XML 字段映射名称 `xml:"xxx"`,发起 XML 格式请求时,XML 中的相应标签名需保持跟结构体中的字段名大小写一致,才能正确解析。