播放2.5 Deadbolt-2的@subjectPresentOr从Java迁移 - >斯卡拉

时间:2016-12-15 18:23:24

标签: scala playframework deadbolt-2

我将现有的Java Play 2.5应用程序迁移到Scala,并在视图main.scala.html中找到以下deadbolt-2subjectPresentOr的使用:

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

将所有控制器和操作迁移到Scala(并从Java更改deadbolt-2依赖关系 - &gt; Scala)后,由于subjectPresentOr需要@subjectPresentOr类型的隐式请求,我得到以下编译器错误1}}:

AuthenticatedRequest[Any]

我有一些直觉,为什么......有时......当用户尚未登录时,没有类型deadbolt-2 main.scala.html:49: could not find implicit value for parameter request: be.objectify.deadbolt.scala.AuthenticatedRequest[Any] 的请求但是超类类型AuthenticatedRequest[_],并且它不能正确地与其子类隐式匹配play.api.mvc.RequestHeader

问题是为什么它首先在Java版本中起作用? {{3}}的Java版本不需要任何隐式请求:)

要在Scala版本中修复它,我会使用模式匹配来包装AuthenticatedRequest[_]块,以发现隐式请求的动态类型,并且只有当其动态类型为@subjectPresentOr时,我才会显示块并明确地向AuthenticatedRequest[_]传递该类型的缩小请求。虽然这不是超级优雅但我无法用其他方式表达......

1 个答案:

答案 0 :(得分:1)

Play的Java版本通过ThreadLocals可以使用Http.Context,而Scala版本使用请求。这些可能是隐含的或明确的。

查看您的控制器,当您将Deadbolt添加到某个操作时,您将收到AuthenticatedRequest

的非Deadbolt动作
def foo = Action { request =>
  // request is of type Request
}

会收到类型为request的{​​{1}},而受Deadbolt保护的行为相同

Request

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

如果您要将AuthenticatedRequest转换为Request,因为您正在调用包含Deadbolt约束的模板,但您的控制器操作不受约束,则可以使用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创建实例。