복붙노트

[SCALA] : 액션 구성을 구현하는 방법

SCALA

: 액션 구성을 구현하는 방법

다음 액션 빌더 구현을 감안할 때 :

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

나는 뭔가를 놓치고 있습니까? 텍사스.

해결법

  1. ==============================

    1.기능 비동기은 미래 [SimpleResult]를 기대하고 있지만, 중첩 된 SecuredAction.async 상단 SignedAction.async (샘플 코드에서이 클래스로 요청을 선언 생략하고 SignedAction 두 번 선언 된 것을 노트)에 액션을 반환합니다.

    기능 비동기은 미래 [SimpleResult]를 기대하고 있지만, 중첩 된 SecuredAction.async 상단 SignedAction.async (샘플 코드에서이 클래스로 요청을 선언 생략하고 SignedAction 두 번 선언 된 것을 노트)에 액션을 반환합니다.

    당신은 서명 요청에 적용하여 SignedAction 내에서 중첩 된 SecuredAction의 결과를 구성 할 수 있습니다.

    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없이 수행 할 수 있습니다.

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

    구성은 미래 [결과] 주위를 수행 할 수 있습니다 :

    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) } 
        }
      }
    }
    
  2. ==============================

    2.당신이 ActionBuilders를 구성 할 수 사용하여 액션 지퍼

    당신이 ActionBuilders를 구성 할 수 사용하여 액션 지퍼

    import jp.t2v.lab.play2.actzip._
    
    object MyController extends Controller {
    
      val MyAction = SignedAction zip SecuredAction 
    
      def doSomething = MyAction.async(parse.json) { case (signedReq, secureReqeq) =>
        Future.successful(Ok)
      }
    }
    

    JSON 구문 분석 한 번만 실행됩니다 :)

  3. ==============================

    3.단순화 @applicius의 대답 내가 비동기가 / 미래는 별도의 문제라고 생각, 그것은 미래없이 할 수 있다고 생각합니다.

    단순화 @applicius의 대답 내가 비동기가 / 미래는 별도의 문제라고 생각, 그것은 미래없이 할 수 있다고 생각합니다.

    아주 간단하게 선물 및 비동기 제거, 우리는이를 얻을 :

        def signed[A](signedBlock: SignedRequest[A] => Result)(implicit req: Request[A]) = signedBlock(SignedRequest(req))
        def secured[A](securedBlock: SecuredRequest[A] => Result)(implicit req: Request[A]) = securedBlock(SecuredRequest(req))
    
        //the use is the same as with Futures except for no async
    
        def doSomething = Action(parse.json) { implicit req =>
             signed[JsValue] { signedReq => secured[JsValue] { securedReq =>
             Ok  
        } } }
    
  4. from https://stackoverflow.com/questions/25105558/play-how-to-implement-action-composition by cc-by-sa and MIT license