Beego默认不读取RequestBody,必须在app.conf中设置copyrequestbody = true,否则c.Ctx.Input.RequestBody为空;启用后可用json.Unmarshal解析JSON数据到struct或map。

Beego 默认不自动读取请求体(RequestBody),直接调用 c.Ctx.Input.RequestBody 会返回空切片,必须显式启用才能拿到 JSON 数据。
必须开启 copyrequestbody = true
Beego v1 和 v2 均要求在 conf/app.conf 中设置:
copyrequestbody = true
否则 c.Ctx.Input.RequestBody 始终为空,无论前端是否发送了合法 JSON。这个配置控制框架是否把原始请求体缓存到内存供后续读取——它不是可选优化项,而是 JSON 解析的前提。
- 不加这行,
c.Ctx.Input.RequestBody返回[]byte{},json.Unmarshal必然失败 - 该配置对所有请求生效,无性能隐患(Beego 内部做了合理缓冲)
- v2 版本仍沿用此配置,未改为默认开启
用 json.Unmarshal 解析到 struct 或 map
拿到原始字节后,用标准库 json.Unmarshal 解析。推荐解析到 struct(类型安全、字段校验方便),也可临时用 map[string]interface{} 快速调试:
struct 示例:
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Active bool `json:"active"`
}
func (c *UserController) Post() {
var u User
if err := json.Unmarshal(c.Ctx.Input.RequestBody, &u); err != nil {
c.Ctx.ResponseWriter.WriteHeader(400)
c.Ctx.WriteString("invalid json: " + err.Error())
return
}
// u 已填充,可继续业务逻辑
}
- struct 字段必须首字母大写(导出),否则
json.Unmarshal无法赋值 -
json:tag 是必需的,否则字段名不匹配(如前端发{"user_name":"a"},struct 字段需写UserName string `json:"user_name"`) - 若解析数组(如
[{"id":1},{"id":2}]),声明为var users []User即可
别用 GetString("xxx") 读 JSON 字段
c.GetString("key") 只从 URL 查询参数(?key=val)或表单字段(application/x-www-form-urlencoded)中提取,对 application/json 请求体完全无效。
- 即使 JSON 里有
{"id":"123"},c.GetString("id")也返回空字符串 - 这是初学者最常踩的坑:误以为 Beego 会自动解析 JSON body 到字符串参数池
- 只有
c.Ctx.Input.RequestBody(配合copyrequestbody = true)才是唯一可靠入口
ServeJSON 不负责接收,只负责返回
c.ServeJSON() 是输出方法,和接收 JSON 完全无关。它只做三件事:序列化 c.Data["json"]、设 Content-Type、写响应体。它不会帮你读请求、也不会自动解析任何输入。
- 常见错误写法:
c.Data["json"] = c.Ctx.Input.RequestBody→ 这只是把原始字节当字符串塞进 JSON,结果是乱码或非法 JSON - 正确流程永远是:启用
copyrequestbody→ 读RequestBody→json.Unmarshal到变量 → 处理业务 →c.Data["json"] = result→c.ServeJSON() - 如果只是想回显接收到的 JSON,仍需先
Unmarshal成 Go 类型再赋值给c.Data["json"],不能跳过解析步骤
真正容易被忽略的是 copyrequestbody = true 这一行配置——它不出现在任何路由或控制器代码里,却决定整个 JSON 接收链路是否成立。漏掉它,后面所有解析逻辑都只是在处理空数据。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











