저는 프레임 워크 2.3의 ActionBuilder와 동작을 동적으로 작성할 수있는 andThen 메소드를 정말 좋아합니다. 당신이 추측 수 있듯이Play framework 2.3 ActionBuilder composition issue
def showHomepage = RedirectingAction andThen
AuthenticatedAction andThen NotificationAction async { request =>
Future {
Ok(views.html.homepage.render(request.user, request.notifications))
}
}
이 NotificationAction이 AuthenticatedAction에 따라, 따라서 사용자 개체를 포함 AuthenticatedRequest이 필요합니다 :
는 여기에 액션 구성을 사용하는 방법의 조각입니다.
코드가 뿌려 :
object NotificationAction extends ActionBuilder[NotificationAuthRequest] {
def invokeBlock[A](request: AuthenticatedRequest[A], block: (NotificationAuthRequest[A]) => Future[Result]) = { ...
오류이다 객체 생성 불가능한 입력의 특성에 ActionFunction 방법 invokeBlock 때문에 [A] (요청 : play.api.mvc.Request [A] 블록 : controllers.v3.ScalaHomepageController.NotificationAuthRequest [A] => scala.concurrent.Future [play.api.mvc.Result] scala.concurrent.Future [play.api.mvc.Result]가 정의되지 않았습니다.
분명히 허용되는 것 :
def invokeBlock[A](request: Request[A], block: ...
하지만 누군가가이 빛을 던질 수 있다면
def invokeBlock[A](request: AuthenticatedRequest[A], block: ...
난 정말 감사하겠습니다. 어쩌면 내 접근 방식이 잘못되었을 수도 있지만 나중에 혼합 할 수있는 작업이 더 많아지기 때문에 미리 작성된 액션 (ActionFunction 사용)과 같은 아이디어가 마음에 들지 않습니다. 난 당신이 ActionRefiners 및 ActionTransformers이 필요합니다 생각하는 문서를 읽기
case class AuthenticatedRequest[A](val user: Option[User], request: Request[A]) extends WrappedRequest(request)
case class NotificationAuthRequest[A](val user: Option[User], val notifications: Option[List[UserNotificationData]], request: Request[A]) extends WrappedRequest(request)
object RedirectingAction extends ActionBuilder[Request] {
def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
Future {
Redirect(REDIRECT_URL + request.uri + paramString)
}
}
}
object AuthenticatedAction extends ActionBuilder[AuthenticatedRequest] {
def invokeBlock[A](request: Request[A], block: (AuthenticatedRequest[A]) => Future[Result]) = {
request.cookies.get("uid") map {
cookie =>
val user = userClient.getUserById(userId(cookie)).get
block(AuthenticatedRequest[A](user, request))
} getOrElse {
block(AuthenticatedRequest[A](userClient.getUserById(uid).get, request))
}
}
def userId(cookie: Cookie) = {
if(AppUtil.isProd) cookie.value else IMPERSONATE_ID.getOrElse(cookie.value)
}
}
object NotificationAction extends ActionBuilder[NotificationAuthRequest] {
def invokeBlock[A](request: AuthenticatedRequest[A], block: (NotificationAuthRequest[A]) => Future[Result]) = {
request.user.map {
user => block(NotificationAuthRequest[A](Some(user), userClient.getNotifications(user.getId).get.map(_.toList), request))
}.getOrElse {
block(NotificationAuthRequest[A](None, None, request))
}
}
}
감사 :
이 내가 생각 해낸 것입니다! 이것은 정말로 좋아 보인다. 나는 이것을 오늘 시험해보고, 그것이 작동하는지에 관해 당신에게 알릴 것이다 :) –
나는 거의 거기에있다! ActionRefiner 문제가 반환 유형이므로 (scala.concurrent.Future [scala.Either [play.api.mvc.Result, P [A]]]) 더 많은 작업을해야합니다. 결과를 반환하고 싶지 않습니다. 다음과 같이 반환하고 싶습니다. 두 경우 모두 NotificationAuthRequest [A] (없음, 없음, 요청). –
대신'ActionTransformer'를 사용할 수 있어야합니다. 시도해 봤어? – bjoernhaeuser