2016-12-15 13 views
1

Я мигрирующие существующий Java Play 2.5 приложения к Scala и нашел в представлении main.scala.html использование следующего deadbolt-2 класса subjectPresentOr:Play 2,5 Deadbolt-2 @subjectPresentOr миграции из Java -> Scala

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

После перенастройки всех контроллеров и действий в Scala (и изменения зависимости ригеля-2 из Java -> Scala) Я получаю следующее сообщение об ошибке компилятора из-за того, что subjectPresentOr требует неявного запроса типа AuthenticatedRequest[Any]:

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

и у меня есть какая-то интуиция, почему ... несколько раз, например. когда пользователь еще не вошел в систему, нет запроса типа deadbolt-2's AuthenticatedRequest[_], но класс суперкласса play.api.mvc.RequestHeader и он не может быть по праву неявным образом согласован с его подклассом AuthenticatedRequest[_].

Вопрос в том, почему это работает в версии Java в первую очередь? версия Java из @subjectPresentOr не требует какого-либо неявного запроса :)

Чтобы исправить это в версии Scala, я бы обернуть @subjectPresentOr блок с сопоставлением с образцом, чтобы обнаружить динамический тип неявного запроса и только если его динамический типа is AuthenticatedRequest[_] Затем я покажу блок и передам @subjectPresentOr явно суженный запрос этого типа. Это не очень элегантно, но я не могу представить другого способа ...

ответ

1

Версия Java для игры имеет Http.Context, доступный для нее через ThreadLocals, тогда как версия Scala использует запросы. Они могут быть неявными или явными.

Посмотрите на свои контроллеры, когда вы добавите Deadbolt к действию, вы получите AuthenticatedRequest. Таким образом, не-Deadbolt действие

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

получит request типа Request, в то время как те же действия защищены Deadbolt

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

получает request типа AuthenticatedRequest.

Если вы хотите преобразовать 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 из существующих Request и без Subject с использованием new AuthenticatedRequest(request, None).

+0

@ (Steve Chalonder) Спасибо, да, это все имеет смысл. Я думаю, проблема решена с помощью 'actionBuilder.WithAuthRequestAction(). DefaultHandler()' в каждом действии, которое возвращает 'RequestHeader'. btw - это более короткая версия: 'actionBuilder.WithAuthRequestAction()()'? еще раз спасибо за помощь и за очень чистый код Deadbolt-2, Play должен учиться у него, например.относительно чистого дизайна, отделяющего Java от Scala, вместо того, чтобы запутать 'play.x' vs' 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-builders и https://deadbolt-scala.readme.io/docs/action-composition. –

 Смежные вопросы

  • Нет связанных вопросов^_^