在Play2中,可以组合多个Action
自定义Action
可以通过继承ActionBuilder
来定义一个Action,Play2中自带的Action就是一个默认实现,如下是自定义一个Action
,用于对每个请求打印信息。
1 | object LoggingAction extends ActionBuilder[Request] { |
可以通过如下的方法来使用这个自定义的Action
:
1 | def custom() = LoggingAction { |
这样,在每次请求时就会打印“Calling action”信息。
组合Action
在开发时,经常遇到会对每一个Action
进行一些通用的处理,如日志, 权限等,在Play2中,可以将它们定义成不同的Action
,然后将它们组合起来。
可以通过继承Action
来创建新的Action
,它是一个接收其他Action
的case class
。
1 | case class Logging[A](action: Action[A]) extends Action[A] { |
也可以通过Action.async
方法来定义一个接收其他Action
的参数,如
1 | def logging[A](action: Action[A]) = Action.async(action.parser) { request => |
也可以通过ActionBuilder
的composeAction
方法来将它本身的Action
组装到其他Action
中,如
1 | object LoggingAction extends ActionBuilder[Request] { |
可以通过以下方法来使用logging
方法:
1 | def custom() = logging { |
更复杂的Action
可以通过组合Action
来修改request对象,如:
1 | def xForwardedFor[A](action: Action[A]) = Action.async(action.parser) { request => |
也可以修改返回的结果,如:
1 | def addUaHeader[A](action: Action[A]) = Action.async(action.parser) { request => |
不同的请求类型
ActionFunction
是一个作用于request的方法,它可以用于权限,认证,查询数据库对象等。有以下内置的ActionFunction
:
ActionTransformer
:可以用来修改request,如增加一些额外的信息。ActionFilter
:可以用来拦截某些不符合条件的请求,不用来改变请求的值。ActionRefiner
:是上面2个的父类ActionBuilder
:以Request
作为输入参数,生成Action,是上面3个的父类,最通用的类。
认证
以下是一个认证的例子,通过组合以上的ActionFunction
。
首先,自定义一个请求类,并且定义Action
1 | class UserRequest[A](val username: Option[String], request: Request[A]) extends WrappedRequest[A](request) |
添加一些额外的信息,生成另一个请求对象
1 | class ItemRequest[A](val item: Item, request: UserRequest[A]) extends WrappedRequest[A](request) { |
然后对请求信息进行转换
1 | def ItemAction(itemId: String) = new ActionRefiner[UserRequest, ItemRequest] { |
验证请求内容
1 | object PermissionCheckAction extends ActionFilter[ItemRequest] { |
最后将所有的转换组合在一起:
1 | def tagItem(itemId: String, tag: String) = |