beego 默认不读取 requestbody,需在 app.conf 中配置 copyrequestbody = true 并重启服务;处理 json 须用 json.unmarshal 而非 parseform;返回 json 必须调用 servejson(),且结构体字段须首字母大写并正确添加 json: 标签。

Beego 默认不读取 RequestBody,必须显式启用
Beego 默认丢弃原始请求体,this.Ctx.Input.RequestBody 始终为空 slice。这不是 bug,而是设计选择——为避免无谓内存拷贝。若你用 POST 发送 application/json,却在控制器里直接打印 this.Ctx.Input.RequestBody 得到 [],八成是忘了配 copyrequestbody = true。
实操建议:
- 在
conf/app.conf顶层(非某个环境段)添加:copyrequestbody = true - 修改后必须重启服务,热重载不生效
- 该配置影响所有请求,无粒度控制;如需按路由开关,得自己写中间件拦截并手动读取
解析 JSON 不能用 ParseForm,必须用 json.Unmarshal
this.ParseForm() 只处理 application/x-www-form-urlencoded 和 multipart/form-data,对 application/json 完全无效。常见错误是:前端发 JSON,后端还调 GetString("user_id"),结果永远返回空字符串。
正确做法是:
- 定义结构体,字段首字母大写(导出),并带
json:标签,例如:Userid string `json:"user_id"` - 调用:
err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)—— 别漏& - 检查
err,不要忽略解析失败(比如字段类型不匹配、JSON 格式非法)
返回 JSON 必须调 ServeJSON(),Data["json"] 不会自动触发渲染
只写 this.Data["json"] = obj 是无效的。Beego 不会因此把响应设为 application/json,也不会序列化 obj;它只是把 obj 当作模板变量存着,最终可能返回 HTML 或空白页。
关键动作只有这一步:
- 赋值后立刻调用:
this.ServeJSON() - 如需自定义状态码(如创建成功返回 201),在
ServeJSON()前加:this.Ctx.ResponseWriter.WriteHeader(201) -
ServeJSON()自动设置Content-Type: application/json; charset=utf-8,无需手动写 Header
结构体字段标签写错或遗漏,会导致 JSON 字段为空
这是最隐蔽的问题:数据库查出数据、结构体也赋了值,但 ServeJSON() 返回全是 null 或空字符串。90% 情况是字段没加 json: 标签,或拼写与前端期望不一致(比如前端要 user_name,你写了 json:"username")。
检查要点:
- 每个需要输出的字段都必须有
json:标签,包括嵌套结构体里的字段 - 可选字段可用指针 +
omitempty,但慎用:Name *string `json:"name,omitempty"`—— 若前端依赖该字段存在,就别加omitempty - 零值字段(
""、0、false)默认会被序列化出来,符合预期;乱加omitempty反而让前端收不到字段
真正容易被忽略的是:结构体字段导出规则和 JSON 标签的耦合性。小写字母开头的字段,无论有没有 json: 标签,都无法被 json.Marshal 序列化——Beego 的 ServeJSON() 底层就是调它。所以不是“标签错了”,而是“字段根本不可见”。











