struct属性应该为可导出的,首字母大写
在调用ServeJSON
之后,会设置content-type
为application/json
,然后同时把数据进行JSON序列化输出
func (c *MainController) Get() {
mystruct := {...}
c.Data["json"]=&mystruct
c.ServeJSON()
}
在调用ServeXML
之后,会设置content-type
为application/xml
,同时数据会进行XML序列化输出
func (c *MainController) Get() {
mystruct := {...}
c.Data["xml"]=&mystruct
c.ServeXML()
}
调用ServeJSONP
之后,会设置content-type
为application/javascript
,然后同时把数据进行JSON序列化,根据请求的callback参数设置jsonp输出
func (c *MainController) Get() {
mystruct := {...}
c.Data["jsonp"]=&mystruct
c.ServeJSONP()
}
URLFor()
函数就是用于构建指定函数的URL
它把对应控制器的函数名结合字符串作为第一个参数,其余参数对应URL中的变量,位置变量添加到URL中作为查询参数
下面定义了一个相应的控制器:
type TestController struct { beego.Controller }
func (t *TestController) Get() { t.Data["Username"] = "astaxie" t.Ctx.Output.Body([]byte("ok")) } func (t *TestController) List() { t.Ctx.Output.Body([]byte("i am list")) } func (t *TestController) Params() { t.Ctx.Output.Body([]byte(t.Ctx.Input.Params()["0"] + t.Ctx.Input.Params()["1"] + t.Ctx.Input.Params()["2"])) } func (t *TestController) Myext() { t.Ctx.Output.Body([]byte(t.Ctx.Input.Param(":ext"))) } func (t *TestController) GetUrl() { t.Ctx.Output.Body([]byte(t.URLFor(".Myext"))) }
下面是我们注册的路由:
beego.Router("/api/list", &TestController{}, "*:List")
beego.Router("/person/:last/:first", &TestController{})
beego.AutoRouter(&TestController{})
那么通过URLFor()
可以获取相应的URL地址
beego.URLFor("TestController.List") // 输出 /api/list
beego.URLFor("TestController.Get", ":last", "xie", ":first", "asta") // 输出 /person/xie/asta
beego.URLFor("TestController.Myext") // 输出 /Test/Myext
beego.URLFor("TestController.GetUrl") // 输出 /Test/GetUrl
默认情况下,beego已经注册了URLFor()
函数,用户可以通过如下代码进行调用
{{urlfor "TestController.List"}}
为什么把URL写死在模板中,反而要动态构建?有两个理由:
- 反向解析通常比硬编码URL更直观,同时更重要的是可以只在一个地方改变URL,而不用带出乱找
- URL创建会处理特殊字符的转义和unicode数据
flash数据主要用于在两个逻辑之间传递临时数据,flash中存放的所有数据会在紧接着的下一个逻辑调用后删除
flash数据一般用于传递提示和错误消息,它适合POST/REDIRECT/GET模式
// Get 显示设置信息 func (c *MainController) Get() { flash := beego.ReadFromRequest(&c.Controller) if n, ok := flash.Data["notice"]; ok { // 显示设置成功 c.TplName = "set_success.html" } else if n, ok = flash.Data["error"]; ok { // 显示错误 c.TplName = "set_error.html" } else { // 显示默认页面 c.Data["list"] = GetInfo() c.TplName = "setting_list.html" } }
// Post 处理设置信息 func (c *MainController) Post() { flash := beego.NewFlash() setting := Settings{} valid := Validation{} c.ParseForm(*setting) if b, err := valid.Valid(setting); err != nil { flash.Error("Setting invalid") flash.Store(&c.Controller) c.Redirect("/setting", 302) } else if b != nil { flash.Error("validation error") flash.Store(&c.Controller) c.Redirect("/setting", 302) return }
saveSetting(setting) flash.Notice("Setting saved") flash.Store(&c.Controller) c.Redirect("/setting", 302)
}
上面的代码执行逻辑大概是这样的:
Get()
方法执行,因为没有flash数据,所以显示设置界面- 用户设置信息之后点击提交,执行
Post()
,然后初始化一个flash,通过验证,验证出错或者验证不通过设置flash的error信息,如果通过了保存设置,设置flash的notice信息 - 设置完成后跳转到GET请求
- GET请求获取到了falsh信息,然后执行相应的逻辑,如果出错显示出错的页面,如果成功显示成功页面
默认情况下ReadFromRequest()
函数已经实现了读取的数据赋值给flash,所以在模板中可以这样读取数据:
{{.flash.error}}
{{.flash.warning}}
{{.flash.notice}}
flash对象有三个级别的设置:
- Notice 提示信息
- Warning 警告信息
- Error 错误信息