gpt4 book ai didi

scala - Play : How to implement action composition

转载 作者:行者123 更新时间:2023-12-01 09:56:43 25 4
gpt4 key购买 nike

给定以下 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))
}
}

如何组合它们?我尝试了以下...

object MyController extends Controller {

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

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

/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) {
^

我错过了什么吗?发送。

最佳答案

函数 async 需要一个 Future[SimpleResult],但是嵌套的 SecuredAction.async 返回一个 Action 到顶部 SignedAction.async(请注意,在您的示例代码中,您省略了将请求声明为 class 并且 SignedAction 声明了两次)。

您可以将嵌套的 SecuredAction 的结果应用于 SignedAction 并将其应用于已签名的请求。

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
}
}

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

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) }
}
}
}

关于scala - Play : How to implement action composition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25105558/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com