Samsara Aquarius已完成,是时候总结一下Play Framework的一些有用的东西和一些坑了~这里对应的Play版本为 2.5.2。
Action, Controller 和 Result
在Play的Web开发中,Action, Controller 和 Result 这三个东西最为重要了。我们一个一个来解释:
Result
Result
代表HTTP请求的结果,它包含header和body两部分。Play内部封装了常见的HTTP response状态,可以在这些Status的基础上生成Result,比如200 OK
:
Action
每个Action相当于一个Request => Result
类型(处理请求并返回结果)的函数,即每个Action都接受一个Request
对象(代表HTTP请求),并产生Result
对象(代表HTTP回应)。
Play Framework 2底层是基于Netty实现的,因此Action
经过处理以后会在Netty通信层执行(Reactor模式)。关于Action的详细实现,后边我还会专门写一篇文章分析。
Controller
在Play中,Controller里的函数用于生成Action。其实Action就相当于处理请求的函数,只不过将普通的函数包装了一层而已(继承关系:Action <:< EssentialAction <:< (RequestHeader => Accumulator[ByteString, Result])
),因此调用这些函数其实就是在调用Action中包装的函数。
Session、Cookie与Flash
Play中处理Session、Cookie的语法都比较简洁。比如Cookie的添加与删除:
|
|
Session的使用也类似:
|
|
但是Play里的session有个坑,它没实现expiration的功能,因此需要我们自己在session中加个时间戳,然后自己实现expiration的逻辑。
另外还有个大坑!如果需要添加session的话,需要这样:
|
|
因为withSession(s)
方法会将s
设为当前的session,原先的session将会被抹掉。
。所以一定要把原先的session加上,要不然原先的session会丢失。
Flash和Session类似,但Flash只在一个request内有效,多用于request之间数据的传递:
|
|
自定义Action
比如有一些逻辑中,我们需要验证用户是否登录,如果没有登录就自动跳转到登录界面。如果在每个Action中都写上登录验证逻辑的话会非常不优美,因此我们可以自定义一个AuthenticatedAction
,里面包装了权限验证的逻辑:
|
|
我们自定义的Action需要实现ActionBuilder[Request]
接口,并重写invokeBlock
函数。
拦截器
在Play中使用Filter也非常方便。比如我们想给应用添加安全拦截器,我们可以写一个Filter:
|
|
其中我们通过依赖注入获取安全拦截器SecurityHeadersFilter
实例。然后,我们在application.conf
中配置拦截器:
|
|
依赖注入
Play Framework 2.4.0开始又引入了依赖注入(学习Spring大乱炖的节奏)。之前写了一篇总结:Play Framework 2.5 | Dependency Injection总结。
Twirl模板引擎
这次开发还顺便玩了玩Play 2的Twirl模板引擎,用起来还比较顺手~不过现在一般都用前后端分离的架构了,后端模板引擎也用的少了。
微服务架构思考
用Play做微服务应用是一个不错的选择,那么如何将单体架构重构成微服务架构呢?这里面就有一个主要的问题:如何将各个组件解耦。一种最简单的思路就是用Play实现一个API Gateway作为网关服务(需要多实例部署+负载均衡+高可用),API Gateway将请求分派到各个组件中,组件之间通过Actor进行通信。可以总结为两点:事件驱动+异步通信。事件驱动可以使整个微服务架构更加灵活,各个组件的耦合度降低,而基于Akka Actor的异步通信可以提高并发性能,提高吞吐量。当然实际生产环境中还要考虑容错、高可用等等的问题,设计起来会更加复杂。
TODO
- Play 2.5 Streaming(Iteratees/Enumerator/Akka Stream)