在 Gin 中,c.BindJSON 和 c.JSON 是前后端交互的两个核心操作,它们构成了数据从前端到后端再返回前端的完整链路。
1. c.BindJSON:接收前端数据
假设前端发送 POST 请求:
json
{"title":"学Gin","status":false}
后端代码:
go
var body struct {
Title string `json:"title"`
Status bool `json:"status"`
}
c.BindJSON(&body)
赋值过程详解:
-
读取 Body
- Gin 从 HTTP 请求中获取请求 Body。
- Body 是原始 JSON 数据:
{"title":"学Gin","status":false}
-
解析 JSON
- Gin 调用 Go 标准库
encoding/json对 JSON 进行解析。
- Gin 调用 Go 标准库
-
结构体字段匹配
- 标签
json:"title"对应 Go 的Title - 标签
json:"status"对应 Go 的Status
- 标签
-
填充值
"title":"学Gin"→body.Title = "学Gin""status":false→body.Status = false
此时,结构体 body 中的数据已经完全对应前端发送的数据。
go
fmt.Println(body.Title) // 输出: 学Gin
fmt.Println(body.Status) // 输出: false
总结:
c.BindJSON的作用是"拆包 + 填字段",把前端 JSON 数据装入 Go 结构体中,方便后续业务逻辑使用。
2. c.JSON:返回数据给前端
处理完数据后,后端需要把结果返回给前端,常用方法是 c.JSON。
go
c.JSON(200, gin.H{
"message": "创建成功",
"todo": body,
})
执行过程:
-
接收 Go 对象
gin.H是 map[string]interface{} 的简写,用于快速构造 JSON 数据- 结构体
body也可以直接返回
-
序列化 JSON
- Gin 内部使用
encoding/json.Marshal将 Go 对象转换成 JSON 字符串 - 结构体标签
json:"..."决定了 JSON 字段名Title→"title"Status→"status"
- Gin 内部使用
-
返回 HTTP 响应
- 状态码 200
- 响应 Body 为 JSON 字符串:
json
{
"message": "创建成功",
"todo": {
"title": "学Gin",
"status": false
}
}
总结:
c.JSON的作用是"打包 + 发快递",把 Go 对象转换成 JSON 返回给前端。
3. 前后端完整交互流程
txt
前端 JSON.stringify → 发 POST 请求
↓
Gin c.BindJSON → 装进结构体
↓
业务逻辑处理
↓
Gin c.JSON → 转 JSON → 返回前端
↓
前端 JSON.parse → 更新页面
示例代码:
go
type Todo struct {
Title string `json:"title"`
Status bool `json:"status"`
}
r.POST("/todos", func(c *gin.Context) {
var body Todo
if err := c.BindJSON(&body); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
// 假设保存数据库成功
c.JSON(200, gin.H{
"message": "创建成功",
"todo": body,
})
})
4. 总结
| 方法 | 作用 | 数据方向 |
|---|---|---|
c.BindJSON(&struct) |
接收前端 JSON,填入 Go 结构体 | 前端 → 后端 |
c.JSON(status, obj) |
将 Go 对象转换成 JSON,返回前端 | 后端 → 前端 |
结合使用
c.BindJSON+c.JSON,就完成了前后端的数据闭环,实现了完整的请求处理和响应返回。