beego控制器必须嵌入beego.controller且由框架自动实例化,不可手动new;需通过beego.router等显式注册路由,方法名须首字母大写、无参数、无返回值;响应方式(tplname/servejson)互斥,不可混用。

beego.Controller 是控制器的基类,不是手动 new 出来的
Beego 的控制器必须继承 beego.Controller,但你不会也不该用 new() 或 &MyController{} 显式实例化它。框架在路由匹配后自动创建实例并调用对应方法(如 Get()、Post())。手动 new 会导致 Ctx、Data 等核心字段为 nil,后续调用 this.TplName 或 this.ServeJSON() 直接 panic。
正确做法是定义结构体并嵌入 beego.Controller:
type UserController struct {
beego.Controller
}
func (c *UserController) Get() {
c.Data["json"] = map[string]string{"msg": "hello"}
c.ServeJSON()
}
路由注册必须显式绑定控制器方法
Beego 不会自动扫描控制器方法,所有接口必须通过 beego.Router()、beego.AutoRouter() 或 beego.RESTRouter() 显式注册。漏掉这步,请求 404,控制台也不会报错——这是新手最常卡住的地方。
-
beego.Router("/user", &UserController{}, "get:Get"):指定 HTTP 方法与控制器方法映射 -
beego.AutoRouter(&UserController{}):按约定将/user/Get→Get(),但路径含大写字母,不推荐用于 API -
beego.RESTRouter(&UserController{}):自动绑定 RESTful 方法(Get()→GET,Post()→POST),适合标准 API
注意:AutoRouter 和 RESTRouter 的参数是 *UserController 类型,不是字符串名,传错类型编译不报错但运行时无响应。
控制器方法必须是 public 且无参数
Beego 反射调用控制器方法时,只识别首字母大写的导出方法,且签名必须严格为 func(*YourController)。任何带参数、返回值、或小写开头的方法都不会被识别,也不会报错,只是静默忽略。
- ✅ 正确:
func (c *UserController) Post() { ... } - ❌ 错误:
func (c *UserController) post()(小写)、func (c *UserController) Create(name string)(带参)、func (c *UserController) Delete() error(有返回值)
如果需要读取 URL 参数或表单数据,统一通过 c.Ctx.Input.Param()、c.GetString()、c.ParseForm() 等控制器内置方法获取,而不是塞进 handler 签名里。
模板渲染和 JSON 响应不能混用
同一个请求中,c.TplName(模板渲染)和 c.ServeJSON() / c.ServeError() 是互斥的。Beego 内部用一个标志位记录是否已输出响应,第二次调用会 panic 并打印 "write tcp: broken pipe" 类似错误——尤其在开发阶段加了日志或调试语句后容易误触。
- 返回 HTML 页面:设
c.TplName = "user.tpl",然后c.Render() - 返回 JSON:设
c.Data["json"] = xxx,然后c.ServeJSON() - 不要在一个方法里先
c.ServeJSON()再c.Render(),也不要重复调用ServeJSON()
调试时建议用 c.Ctx.WriteString("debug") 快速验证流程,避免过早引入模板或 JSON 输出逻辑。











