代码改变世界

Go Web开发之Revel - 返回值

2013-01-06 18:09  Danny.tian  阅读(3596)  评论(0编辑  收藏  举报

返回值必须返回一个 rev.Result, 它处理response的生成并依附于一个简单的接口:

type Result interface {
    Apply(req *Request, resp *Response)
}

rev.Controller 提供几个方法来生成结果:

  • Render, RenderTemplate - 渲染一个模板, 传递参数.
  • RenderJson, RenderXml - 序列化一个结构的json或xml.
  • RenderText - 返回一个纯文本response.
  • Redirect - 重定向到另一个action或URL
  • RenderFile - 返回一个文件, 通常作为一个附件下载.
  • RenderError - 返回一个 500 response 它渲染 errors/500.html 模板.
  • NotFound - 返回一个 404 response 它渲染 errors/404.html 模板.
  • Todo - 返回一个 stub response (500)

此外,开发人员可以定义他们自己的rev.Result并返回它.

设置状态码 / Content Type

每一个内建的结果都有一个默认的状态码和Content Type. 要重写它们的值只需在response时简单的设置那些要改变的属性:

func (c Application) Action() rev.Result {
    c.Response.Status = http.StatusTeapot
    c.Response.ContentType = "application/dishware"
    return c.Render()
}

渲染

render在action中被调用, mvc.Controller.Render 做了两件事情:

  1. 添加全部的参数到controller的RenderArgs. 使用他们的本地标示符作为key.
  2. 执行模板“views/Controller/Action.html”, 传入controller的RenderArgs作为数据字典.

如果不成功(例如它不能找到模板文件), 它将返回一个ErrorResult替换.

允许开发人员这样写:

func (c MyApp) Action() rev.Result {
    myValue := calculateValue()
    return c.Render(myValue)
}

在他们的模板中使用"myValue". 这通常比显式的构造一个字典更方便, 因为在很多的案例中数据将需要作为本地变量来处理.

注意:Revel通过调用的方法名称来决定模板路径和查找的参数名称.因此, c.Render()可能只能从action中调用.

RenderJson / RenderXml

应用程序可以调用 RenderJson 或 RenderXml 来传入任意的Go类型(通常是一个struct). Revel将用json.Marshal 或 xml.Marshal序列化它.

如果results.pretty=true在app.conf中, 序列化将使用MarshalIndent来完成, 以便输出更优雅的带缩进的比较利于人们查看的版本.

Redirect

一个帮助函数提供了重定向. 它可以被用于两种方式.

1. 重定向一个不带参数的Action

return c.Redirect(Hotels.Settings)

这种形式对提供一个深度的类型安全和独立的路由很有帮助.(它生成自动的URL)

2. 重定向到一个格式化字符串

return c.Redirect("/hotels/%d/settings", hotelId)

这种形式需要必要的参数传递.

它返回一个302(临时跳转)状态码.

添加你自己的Result

下面是一个添加简单Result的示例.

创建类型:

type Html string

func (r Html) Apply(req *Request, resp *Response) {
    resp.WriteHeader(http.StatusOK, "text/html")
    resp.Out.Write([]byte(r))
}

然后在action中使用它

func (c *Application) Action() rev.Result {
    return Html("<html><body>Hello World</body></html>")
}

状态码

每一个Result将默认设置一个状态码.你能通过设置一个你自己的来重写这个默认的状态码.

func (c *Application) CreateEntity() rev.Result {
    c.Response.Status = 201
    return c.Render()
}

 

至此结束.