beego mvc 正确运行需满足四点:controller 必须嵌入 beego.controller;路由注册需下划线导入触发 init();模板须放根目录 views/ 下且后缀为 .tpl/.html/.gohtml;数据字段首字母大写方可被 {{.field}} 访问。

beego.Run() 是启动服务的最简入口,但直接跑起来不等于真正进入 MVC 开发——你得先让 Model、Controller、View 各司其职,且能被框架识别并串联起来。Beego 的 MVC 不是概念包装,而是靠目录约定 + init() 注册 + 结构体嵌入三者硬绑定的。
Controller 必须嵌入 beego.Controller 才有上下文能力
很多人写完结构体就直接注册路由,结果调用 c.Ctx.WriteString() 报 nil pointer panic。原因很简单:beego.Controller 不是接口,是具体结构体,它内部初始化了 Ctx、Data、StartTemplate 等字段。你自定义的 Controller 必须用嵌入方式继承它,而不是实现某个接口。
- ✅ 正确写法:
type IndexController struct { beego.Controller } - ❌ 错误写法:
type IndexController struct {}(哪怕实现了 Get/Post 方法也没用) - 调用
c.ServeJSON()前,确保c.Data["json"] = xxx已赋值,否则返回空对象 - 如果需要在所有 Controller 中统一加日志或鉴权,别改每个
Get(),改Prepare()方法——它是 Beego 自动调用的前置钩子
路由注册必须触发 init() 且路径要全匹配
Beego 路由不是“声明即生效”,而是依赖包导入时触发 init() 函数执行 beego.Router()。如果你在 main.go 里只写了 import "myapp/routers" 却没加下划线前缀,那个 init() 根本不会运行。
- ✅ 正确导入:
_ "myapp/routers"(下划线表示仅执行 init,不引入符号) - ❌ 错误导入:
"myapp/routers"(编译会报 unused import) - 固定路由是全路径匹配:
beego.Router("/user/list", &user.ListController{})不会匹配/user/list/或/user/list?page=1,末尾斜杠和查询参数都不参与匹配 - 想支持可选后缀或参数,得用正则路由:
beego.Router("/user/:id([0-9]+)", &user.DetailController{}, "get:Get")
模板渲染需注意 views 目录位置和扩展名默认规则
Beego 默认只扫描项目根目录下的 views/ 子目录,且只认 .tpl、.html、.gohtml 三种后缀。你把模板放在 controllers/views/ 或命名为 index.tmpl,c.TplName = "index.tpl" 也会报 template: "index.tpl" is undefined。
- 模板文件必须放在项目根目录的
views/下,如views/index.tpl -
c.TplName赋值时**不能带路径前缀**,写"index.tpl",别写"views/index.tpl" - 如果要用
.gohtml,得显式注册:beego.AddTemplateExt("gohtml"),否则模板引擎直接忽略 -
{{.Title}}这类点语法取值,要求传入的数据是 map 或 struct 字段首字母大写(Go 导出规则),小写字段无法访问
init() 没触发,嵌入没写对,模板放错位置——任何一个环节断掉,错误信息都不会直接告诉你缺了什么,只会表现为 404、panic 或空白响应。动手前先确认这四件事是否全部满足,比查半天文档更省时间。











