- 本章介绍几种定义通用 Action 功能的方法.
基本的 Action 组合
我们首先从一个简单的日志装饰器(logging decorator) 开始: 我们想要记录下当前 Action 每次被调用的日志.
我们不直接就定义自己的 Action, 而是首先提供一个用于创建标准 Action 的帮助方法:1def LoggingAction(f: Request[AnyContent] => Result): Action[AnyContent] = { 2 Action { request => 3 Logger.info("Calling action") 4 f(request) 5 } 6}
接着你可以这么来使用: Read More - 什么是 Body 解析器?
HTTP PUT 或 POST 请求含有一个请求体(Body). 请求体可以使用任何格式, 只要在请求头中指定相应的Content-Type即可. 在 Play 中, 一个 Body 解析器 转换请求体为对应的 Scala 值.
然而,HTTP 请求体可能非常的大,这时候 Body 解析器 不可能在解析之前光等着把数据全部加载到内存.BodyParser[A]是个基本的Iteratee[Array[Byte],A], 这就是说它一块一块的接收数据 (只要 Web 浏览器在上传数据) 并计算出类型为 A 的值作为结果.
让我们考虑一下几个例子.- 一个文本型 Body 解析器能够把逐块的字节数据连缀成一个字符串, 并把计算得到的字符串作为结果 (
Iteratee[Array[Byte],String]). - 一个文件型 Body 解析器能够把逐块的字节数据存为一个本地文件, 并以
java.io.File引用作为结果 (Iteratee[Array[Byte],File]). - 一个 s3 型 Body 解析器能够把逐块的字节数据推送给 Amazon S3 并以 S3 对象 ID 作为结果 (
Iteratee[Array[Byte],S3ObjectId]). Read More
- 一个文本型 Body 解析器能够把逐块的字节数据连缀成一个字符串, 并把计算得到的字符串作为结果 (
- 会话和 Flash 域在 Play 中有何不同
如果你不得不要跨多个 HTTP 请求来保存数据, 你可以存在会话或是 Flash 域中. 存储在会话中的数据在整个会话期间可用, 而存储在 Flash 域中数据只对下一次请求有效.
理解到会话和 Flash 数据不是由服务器来存储,而是以 Cookie 机制添加到每一次后续的 HTTP 请求是很重要的. 这也就意味着数据的大小是很受限的 (不到 4 KB) ,而且你只能存储字符串.
当然了, Cookie 值是由密钥签名了的,这使得客户端不存修改 Cookie 数据(或者说这样做会让它失效).
Play 会话不能当成缓存来用. 假如你需要缓存与某一会话相关的数据, 你可以使用 Play 内置的缓存机制并存储一个唯一的 ID 在用户会话中与之关联.会话没有技术上的超时控制. 它在用户关闭 Web 浏览器后就会过期. 如果你的应用需要一种功能性的超时控制, 那就在用户会话中存储一个时间戳,并在应用需要的时候用它 (例如: 最大的会话持续时间, 最大的非活动时间, 等等.).
读取会话值
你可以从 HTTP 请求中获取传入的会话: Read More - 改变默认的 Content-Type
结果内容的类型能够由你所指定的响应体的 Scala 值自动推断出来.
例如:1val textResult = Ok("Hello World!")
将会自动设置Content-Type头为text/plain, 而:1val xmlResult = Ok(<message>Hello World!</message>)
会设置 Content-Type header 为text/xml.小贴士: 这是由
这相当有用, 但是有时候你想手工改变它. 只需要调用 Result 的play.api.http.ContentTypeOf类型类完成的.as(newContentType)方法来创建一个新的,类似的,具有不同Content-Type头的 Result:1val htmlResult = Ok(<h1>Hello World!</h1>).as("text/html")
或者更好点, 用: Read More - 内建的 HTTP 路由器
路由器组件掌管把传入的 HTTP 请求转发到 Action.
一个HTTP 请求可被 MVC 框架看成是一个事件. 这个事主要包含两方面的信息:- 请求路径 (如
/clients/1542,/photos/list), 包括查询字符串 - HTTP 方法 (像 GET, POST, …).
路由定义在conf/routes文件中, 它会被编译. 这表明你可以直接在浏览器上看到路由错误信息: Read More - 请求路径 (如
- 什么是 Action?
多数的请求被 Play 应用接收到,并由Action 进行处理.
一个play.api.mvc.Action简单说来就是一个(play.api.mvc.Request => play.api.mvc.Result)函数,它处理请求并产生一个 result 发送给客户端.1val echo = Action { request => 2 Ok("Got request [" + request + "]") 3}
Action 返回一个play.api.mvc.Result值, 代表着发送给 Web 客户端的 HTTP 响应. 上面的例子中Ok构造了一个 200 OK 的响应,它包含了 text/plain 类型的响应体.
建造一个 Actionplay.api.mvc.Action伴生对象提供有多个帮助方法用于构建 Action 值.
最简单的一个方法是以返回值为Result的表达式块作为参数: Read More - 用 Play 进行工作其实很简单的. 你甚至不需要一个复杂的 IDE, 因为 Play 会在你对源文件作了修改之后自动编译和刷新, 因此你可以很轻易的使用一个简单的文本编辑器来工作.
然而, 使用一个现代的 Java 或 Scala IDE 或给予你很 Cool 生产效率, 比如即时的编译, 良好的重构和调试功能.
Eclipse
生成配置
Play 提供了一条命令简化了 Eclipse 配置. 为转换一个 Play 应用为有效的 Eclipse 项目, 使用eclipsify命令:
无需关联下载依赖的源文件 jars 包:Unmi 注: 对于一个新建的项目,执行 eclipsify 之后会产生 Eclipse 必须的 .project, .classpath 和 .settings 文件,并且这个命令还会创建 test 和 target 目录。Play 1.x 的 play eclipsify 命令有些不同,它会生成一个 eclipse 目录,里面有三个分别用于运行, 调试和测试用的 launch 文件。 Read More1[My first application] $ eclipsify - 这是一个 HTTP 编程 的大纲, 点击以下链接进入各节内容:
- 启动控制台
Play 2.0 控制台是基于 sbt 的为开发而准备的控制吧, 它允许你管理整个 Play 应用的开发周期.
要启动控制台, 进入到现有的 Play 应用的目录,然后运行play脚本:
Unmi 注: 虽然 sbt 是为 Scala 准备的构建工具,但是即使你创建的应用选的是 Java 语言, 我们仍然是要依赖于 sbt. 在 Play 1.x 的时候不存在 Play 控制台,要么就是直接把应用运行起来了。在 Play 1.x 的项目目录下运行 play 命令只会显示简单的帮助信息。
play 命令进入到当前应用的控制台下,提示符是 [应用的名称] $1$ cd /path/to/any/application 2$ play
Read More
- 标准的应用目录布局
Play 应用的目录布局是标准化的,这样可保持尽量的简单. 一个标准的 Play 应用看起来如下:1app → 应用程序源文件 2 └ assets → 待编译的资源文件 3 └ stylesheets → 比如放置 LESS CSS 源文件 4 └ javascripts → 比如放置 CoffeeScript 源文件 5 └ controllers → 应用的控制器 6 └ models → 应用的业务层 7 └ views → 视图模板 8conf → 配置文件和其他无需编译的放在 classpath 下的文件 9 └ application.conf → 主配置文件 10 └ routes → 路由定义文件 11public → 公共资源 12 └ stylesheets → CSS 样式文件 13 └ javascripts → Javascript 脚本文件 14 └ images → 图片 15project → sbt 配置文件 16 └ build.properties → sbt 项目属性配置 17 └ Build.scala → 应用构建脚本 18 └ plugins.sbt → sbt 插件配置 19lib → 不受管理的库依赖 20logs → 标准的日志目录 21 └ application.log → 默认的日志文件 22target → 构建生成的东西 23 └ scala-2.9.1 24 └ cache 25 └ classes → 编译生成的类文件 26 └ classes_managed → 受管理的类文件 (如模板等生成的) 27 └ resource_managed → 受管理的资源文件 (如 Less 等生成的) 28 └ src_managed → 产生的源文件 (如模板等) 29test → 单元和功能性测试的源文件目录
Read More