beego 中应继承 beego.controller 重写 servejson() 方法统一包装 json 响应结构为 {"code":0,"msg":"success","data":{...}},并提供 rendererror() 处理错误响应,避免使用 abort();bconfig.copyrequestbody 与此无关。

Beego 中如何统一设置 JSON 响应结构
Beego 默认的 ctx.JSON() 或 ctx.Output.JSON() 直接输出原始数据,不带状态码、消息字段或统一包装。要实现如 {"code": 0, "msg": "success", "data": {...}} 这类格式,不能靠每次手动拼 map,得在控制器基类或中间件层统一拦截。
推荐做法是继承 beego.Controller,重写 ServeJSON() 方法,并在其中封装标准结构:
func (c *BaseController) ServeJSON(encoding ...bool) {
var (
obj = c.Data["json"]
status = c.Ctx.ResponseWriter.Status()
code = 0
msg = "success"
)
if status >= 400 {
code = status
msg = http.StatusText(status)
}
resp := map[string]interface{}{
"code": code,
"msg": msg,
"data": obj,
}
c.Data["json"] = resp
c.Controller.ServeJSON(encoding...)
}
后续所有继承 BaseController 的控制器调用 c.ServeJSON() 就自动带上标准结构。
为什么不能直接改 beego.BConfig.CopyRequestBody = true
这个配置只影响请求体读取行为,和响应格式完全无关。常见误解是以为开启它就能“接管响应”,其实它只决定是否把 ctx.Input.RequestBody 提前读进内存,对 Output.JSON() 的输出内容无任何干预能力。
容易踩的坑包括:
- 误以为设置了
BConfig某些字段就能改变 JSON 序列化逻辑 - 在
Finish()里试图修改已写出的响应体——HTTP 响应头一旦写出,body 就不可逆 - 用
ctx.ResponseWriter.Write()手动写 JSON,绕过 Beego 的输出流程,导致JSONP、charset头等默认行为丢失
处理错误响应时怎么保持结构一致
Beego 的 c.Abort()(如 c.Abort("400"))会直接终止流程并输出默认错误页,不走 ServeJSON。所以必须避免在 API 场景中用 Abort() 返回业务错误。
正确方式是:在 BaseController 中提供 RenderError(code int, msg string) 方法:
func (c *BaseController) RenderError(code int, msg string) {
c.Data["json"] = map[string]interface{}{
"code": code,
"msg": msg,
"data": nil,
}
c.ServeJSON()
c.StopRun() // 阻止后续执行
}
然后在业务逻辑中按需调用:c.RenderError(401, "token expired")。
注意:不要用 c.Abort("401"),它会跳过 ServeJSON,返回 HTML 错误页。
自定义结构对性能和兼容性的影响
Beego 的 ServeJSON() 默认使用 json.Marshal,你只是在外层套了一层 map,开销极小。但要注意两点:
- 如果
data字段本身已是完整响应结构(比如已有code和msg),重复包装会导致嵌套,需要在ServeJSON()中加判断逻辑 - Beego v2+ 默认启用
gobuffalo/packr等资源打包机制,但不影响 JSON 输出逻辑;若用了自定义JSONEncoder(如jsoniter),需确保你的包装逻辑仍作用于最终传入Marshal的对象 - 前端若依赖
Content-Type: application/json; charset=utf-8,Beego 默认已设置,无需额外操作;但手动WriteHeader后再写 body 可能覆盖该 header
最易被忽略的是:全局错误处理(如 beego.ErrorHandler)不会自动应用你定义的 BaseController 行为,404/500 等非业务错误仍需单独配置 JSON 格式返回。











