Play 2.0 中文资料 - 操控 Result

改变默认的 Content-Type


结果内容的类型能够由你所指定的响应体的 Scala 值自动推断出来.

例如:
1val textResult = Ok("Hello World!")

将会自动设置 Content-Type 头为 text/plain, 而:
1val xmlResult = Ok(<message>Hello World!</message>)

会设置 Content-Type header 为 text/xml.
小贴士: 这是由 play.api.http.ContentTypeOf 类型类完成的.
这相当有用, 但是有时候你想手工改变它. 只需要调用 Result 的 as(newContentType) 方法来创建一个新的,类似的,具有不同 Content-Type  头的 Result:
1val htmlResult = Ok(<h1>Hello World!</h1>).as("text/html")

或者更好点, 用:
1val htmlResult = Ok(<h1>Hello World!</h1>).as(HTML)
注: 使用 HTML 代替 "text/html" 的好处是会为你自动处理字符集,这时实际的 Content-Type 头会被设置为 text/html; charset=utf-8. 过会儿我们就能看到.
操控 HTTP 头

你还能添加 (或修改) Result 的任何 HTTP 头:
1Ok("Hello World!").withHeaders(
2  CACHE_CONTROL -> "max-age=3600",
3  ETAG -> "xx"
4)

注:如是对一个 Result 设置了同一个 Header Key 对应的值,后面的会覆盖前面所设置的值.

Unmi:  上面的 withHeaders() 方法的原型是 Results(.scala) 中的 def withHeaders(headers: (String, String)*): A 方法。正如你看到的,withHeaders() 接收的是多个 (String, String) 元组类型。为什么可写成 CACHE_CONTROL,因为它的类型是字符串,字符串的 -> 操作符的返回值就是一个 (String, String) 元组类型。更多的 Header Key 定义在 play.api.http.HeaderNames 对象中。

为了演示相同 Key 时 Header 的覆盖关系,可以试下列代码:
1Ok("Hello World!").withHeaders(
2  "author" -> "Unmi",
3  "siteFlag" -> "HongKong"
4).withHeaders(
5  "siteFlag" -> "USA"
6)

查看一下它的 Header 信息:
unmi@localhost$ curl -i http://localhost:9000
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
author: Unmi
siteFlag: USA
Content-Length: 12
看到 siteFlag 存在时后面覆盖前面的设置,Key 不同时只添加。

设置和废弃 Cookie

Cookie 就是一种特殊的 HTTP 头,但是我们提供了一系列帮助方法简化了操作.

你可以很轻易的添加 Cookie 到 HTTP 响应中,使用:
1Ok("Hello world").withCookies(
2  Cookie("theme", "blue")
3)

而且, 要废弃先前存储在 Web 浏览器中的 Cookie 可用:
1Ok("Hello world").discardingCookies("theme")

改变基于文本的 HTTP 响应的字符集

对于基于文本的 HTTP 响应,正确处理好字符集是很重要的. Play 处理它的方式是采用 utf-8 为默认字符集.

字符集一方面用于转换文本响应成相应的字节通过网络 Socket 传送, 也用于更改 Content-Type 头为适当的 ;charset=xxx 扩展.

字符集由 play.api.mvc.Codec 类型类自动处理. 仅需要引入一个隐式的 play.api.mvc.Codec 实例到当前作用域中,从而各种操作所用到的字符集:
1object Application extends Controller {
2
3  implicit val myCustomCharset = Codec.javaSupported("iso-8859-1")
4
5  def index = Action {
6    Ok(<h1>Hello World!</h1>).as(HTML)
7  }
8
9}

这里, 因为作用域中存在一个隐式 charset 值, 它会被应用到 Ok(...) 方法来转换 XML 消息成 ISO-8859-1 编码的字节,或者是用于生成值为 text/html; charset=iso-8859-1 的 Content-Type 头.

现在,假如你想知道 HTML 方法是怎么工作的, 看看它的定义: Unmi 注:因为参数用了 implicit 关键字,所以如果在作用域中能找到 implicit 修饰的 Codec 类型变量将被隐式采用。
1def HTML(implicit codec: Codec) = {
2  "text/html; charset=" + codec.charset
3}

假如你需要以通用的方式来处理字符集,你可以在自己的 API 中做同样的事情. 永久链接 https://yanbin.blog/play2-0-tutorials-cn-manipulating-results/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。