Play:如何实现动作组合 [英] Play: How to implement action composition

查看:17
本文介绍了Play:如何实现动作组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下 ActionBuilder 实现:

class SignedRequest[A](request: Request[A]) extends WrappedRequest[A](request) {}

object SignedAction extends ActionBuilder[SignedRequest] {

  def invokeBlock[A](request: Request[A], block: SignedRequest[A] => Future[SimpleResult]) = {
    block(new SignedRequest(request))
  }   
}     

class SecuredRequest[A](request: Request[A]) extends WrappedRequest[A](request) {}

object SecuredRequest extends ActionBuilder[SecuredRequest] {

  def invokeBlock[A](request: Request[A], block: SecuredRequest[A] => Future[SimpleResult]) = {
    block(new SecuredRequest(request))
  }   
}

我该如何组合它们?我试过以下...

How do I combine them? I've tried the following...

object MyController extends Controller {

  def doSomething = SignedAction.async(parse.json) {
    SecuredAction.async(parse.json) { implicit request =>
      Future.successful(Ok)
  }}
}

...但我总是收到以下错误消息:

... but I always get the following error message:

/home/j3d/test/controllers/MyController.scala:37: type mismatch;
[error]  found   : play.api.mvc.Action[play.api.libs.json.JsValue]
[error]  required: scala.concurrent.Future[play.api.mvc.SimpleResult]
[error]       SecuredAction.async(parse.json) {
                                              ^

我错过了什么吗?发送.

Am I missing something? Tx.

推荐答案

Function async 期待一个 Future[SimpleResult],但是嵌套的 SecuredAction.async 将一个 Action 返回到顶部 SignedAction.async(请注意,在您的示例代码中,您省略了将请求声明为 classSignedAction 声明了两次).

Function async is expecting a Future[SimpleResult], but the nested SecuredAction.async is returning an Action to the top SignedAction.async (notes that in your sample code you omit to declare requests as class and SignedAction is declared twice).

您可以将 SecuredAction 嵌套在 SignedAction 中的结果应用到签名请求中.

You can compose result of nested SecuredAction within SignedAction by applying it to the signed request.

package controllers

import scala.concurrent.Future

import play.api._
import play.api.mvc._

case class SignedRequest[A](request: Request[A]) 
    extends WrappedRequest[A](request) {}

object SignedAction extends ActionBuilder[SignedRequest] {

  def invokeBlock[A](request: Request[A], 
    block: SignedRequest[A] => Future[Result]) = 
    block(new SignedRequest(request))

}     

case class SecuredRequest[A](request: Request[A]) 
    extends WrappedRequest[A](request) {}

object SecuredAction extends ActionBuilder[SecuredRequest] {

  def invokeBlock[A](request: Request[A], 
    block: SecuredRequest[A] => Future[Result]) = 
    block(new SecuredRequest(request))

}

object MyController extends Controller {
  def doSomething = SignedAction.async(parse.json) { signedReq =>
    SecuredAction.async(parse.json) { implicit securedReq =>
      Future.successful(Ok)
    } apply signedReq
  }
}

这样的动作组合也可以在没有 ActionBuilder 的情况下完成(这会导致一些额外的复杂性).

Such action composition can also be done without ActionBuilder (which can lead to some extra complexity).

package controllers

import scala.concurrent.Future

import play.api._
import play.api.mvc._

case class SignedRequest[A](request: Request[A])
case class SecuredRequest[A](request: Request[A]) 

object MyController extends Controller {
  def Signed[A](bodyParser: BodyParser[A])(signedBlock: SignedRequest[A] => Future[Result]): Action[A] = Action.async(bodyParser) { req => 
    signedBlock(SignedRequest(req)) 
  }

  def Secured[A](bodyParser: BodyParser[A])(securedBlock: SecuredRequest[A] => Future[Result]): Action[A] = Action.async(bodyParser) { req => 
    securedBlock(SecuredRequest(req)) 
  }

  def doSomething = Signed(parse.json) { signedReq =>
    Secured(parse.json) { implicit securedReq =>
      Future.successful(Ok)
    } apply signedReq.request
  }
}

也可以围绕Future[Result]进行组合:

package controllers

import scala.concurrent.Future

import play.api._
import play.api.mvc._
import play.api.libs.json.JsValue

case class SignedRequest[A](request: Request[A])
case class SecuredRequest[A](request: Request[A]) 

object MyController extends Controller {
  def Signed[A](signedBlock: SignedRequest[A] => Future[Result])(implicit req: Request[A]): Future[Result] = signedBlock(SignedRequest(req))

  def Secured[A](signedBlock: SecuredRequest[A] => Future[Result])(implicit req: Request[A]): Future[Result] = signedBlock(SecuredRequest(req))

  def doSomething = Action.async(parse.json) { implicit req =>
    Signed[JsValue] { signedReq =>
      Secured[JsValue] { securedReq => Future.successful(Ok) } 
    }
  }
}

这篇关于Play:如何实现动作组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆