2014-11-05 34 views
0

我試圖圍繞我的頭玩遊戲動作組合。我的主要參考:https://www.playframework.com/documentation/2.3.6/ScalaActionsCompositionScala玩動作組合:聲明ActionBuilder,通過組合幾個ActionFunction產生動作

這是我想要實現(要能這樣聲明函數在我的控制器)是什麼:

def sensitiveOperation() = Protected {request => ...} 

所以,我的行動計劃是:

/** 
* Now I need to make an Action builder that wraps two things: 
* UserAction (to make sure that request is transformed to UserRequest), 
* and then... an Action that checks if userId has a value (it proceeds by invoking the actual action) 
* , or otherwise return Unauthorized 
*/ 

所以...我有這三樣東西:

class UserRequest[A](val userId: Option[String], request: Request[A]) extends WrappedRequest[A](request) 

object UserAction extends ActionBuilder[UserRequest] with ActionTransformer[Request, UserRequest] { 
    def transform[A](request: Request[A]) = Future.successful { 
    new UserRequest(request.session.get("userId"), request) 
    } 
} 

object CheckUserId extends ActionFilter[UserRequest] { 
    def filter[A](userRequest: UserRequest[A]) = Future.successful { 
    userRequest.userId match { 
     case Some(userIdVal) => None 
     case None => Some(Results.Unauthorized("User is not logged in. Log in first.")) 
    } 
    } 
} 

所有這三樣東西編譯。

我的問題是:如何聲明一個使用UserAction和CheckUserId的操作?

object Protected extends ActionBuilder[Request] { 
    def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = { 
    block(request) 
    } 
    override def composeAction[A](action: Action[A]) = ... ?? how ?? .... 
} 

我試圖在這之下,但它給編譯錯誤:

override def composeAction[A](action: Action[A]) = UserAction andThen CheckUserId 

。附加

現在我可以解決它使用此:

def sensitiveOperation() = (UserAction andThen CheckUserId) {request => ...} 

但是,我仍然瘦ķ那將是更漂亮,如果我可以定義一個名爲「保護」,實際上做同樣的同伴對象(和-ING UserAction和CheckUserId)......,這樣我就可以用原來的想法回去:

def sensitiveOperation() = Protected {request => ...} 

如何實現它?

由於提前, 拉嘎

回答

3

你不能用一個對象做到這一點,因爲對象不能是結果一種表達。但是,您可以將其設置爲def或val,並且您可以將其放入包裝對象中,例如:

package object security { 
    val Protected = UserAction andThen CheckUserId 
} 
+0

我認爲我喜歡您的解決方案更好,更簡潔。謝謝! – 2014-11-05 04:41:06

0

我想我已經找到了如何....

object Protected extends ActionBuilder[UserRequest] { 
    def invokeBlock[A](request: Request[A], block: (UserRequest[A]) => Future[Result]) = { 
    (UserAction andThen CheckUserId).invokeBlock(request, block) 
    } 
}