2016-12-15 77 views
1

我遷移現有的Java播放2.5應用Scala和視圖main.scala.html使用以下deadbolt-2subjectPresentOr的發現:播放2.5呆-2的@subjectPresentOr從Java遷移 - >斯卡拉

@subjectPresentOr() { 
    <ul class="nav navbar-nav navbar-right"> 
    @defining(userProvider.getUser(session())) { user => 
    ... user is present html 
    } 
} { 
    ... user is NOT present html  
} 

遷移所有控制器和行動,斯卡拉後(從Java和改變鎖舌-2的依賴性 - >斯卡拉)我得到以下編譯器錯誤歸因於subjectPresentOr需要AuthenticatedRequest[Any]類型的隱含請求的事實:

main.scala.html:49: could not find implicit value for parameter request: 
    be.objectify.deadbolt.scala.AuthenticatedRequest[Any] 

我有一些直覺,當用戶還沒有登錄時,沒有類型deadbolt-2的AuthenticatedRequest[_]的請求,但超類型號爲play.api.mvc.RequestHeader,並且它不能與其子類AuthenticatedRequest[_]明確匹配。

問題是爲什麼這首先在Java版本中起作用?@subjectPresentOr Java版本不需要任何隱含的要求:)

要修復它在斯卡拉版本我想包的@subjectPresentOr塊與模式匹配來發現的動態類型的隱含請求,且僅當它的動態類型是AuthenticatedRequest[_]然後,我將顯示該塊並明確傳遞給@subjectPresentOr該範圍的縮小請求。這不是超級優雅,但我無法想象任何其他方式...

回答

1

Play的Java版本有一個Http.Context可通過ThreadLocals,而Scala版本使用請求。這些可能是隱含的或明確的。

看着你的控制器,當你添加Deadbolt到一個動作時,你將收到一個AuthenticatedRequest。所以,

def foo = Action { request => 
    // request is of type Request 
} 

非呆行動將收到Request類型的request,而同樣的動作通過呆保護

def foo = actionBuilder.SubjectPresentAction().defaultHandler() { request => 
    // request is of type AuthenticatedRequest 
} 

接收AuthenticatedRequest類型的request

如果你想一個Request轉換爲AuthenticatedRequest,因爲你調用包含呆約束的模板還沒有你的控制器動作是不受約束的,你可以使用WithAuthRequestAction

def foo = actionBuilder.WithAuthRequestAction().defaultHandler() { request => 
    // request is of type AuthenticatedRequest 
} 

如果你注入DeadboltActions代替ActionBuilders,同樣也是如此:

def foo= deadboltActions.SubjectPresent()() { request => 
    // request is of type AuthenticatedRequest 
} 

用戶也可以直接從現有的創建AuthenticatedRequest實例並且使用new AuthenticatedRequest(request, None)沒有Subject

+0

@(史蒂夫查龍德)謝謝,是的,這一切都有道理。我認爲這個問題可以在每個返回RequestHeader的動作中使用'actionBuilder.WithAuthRequestAction()。defaultHandler()'來解決。 btw是一個更短的版本:'actionBuilder.WithAuthRequestAction()()'?再次感謝你的幫助和Deadbolt-2的非常乾淨的代碼,Play應該從中學習例如關於將Java從Scala中分離出來的簡潔設計,而不是將其與'play.x'和'play.api.x'混淆。 –

+0

[ActionBuilders](https://github.com/schaloner/deadbolt-2-scala/blob/master/code/app/be/objectify/deadbolt/scala/ActionBuilders.scala)爲[DeadboltActions]提供了另一種語法( https://github.com/schaloner/deadbolt-2-scala/blob/master/code/app/be/objectify/deadbolt/scala/DeadboltActions.scala)所以'actionBuilder.WithAuthRequestAction()()'是無效的。有關更多詳細信息,請參閱https://deadbolt-scala.readme.io/docs/action-builder和https://deadbolt-scala.readme.io/docs/action-composition。 –