我将现有的Java Play 2.5应用程序迁移到Scala,并在视图main.scala.html
中找到以下deadbolt-2类subjectPresentOr
的使用:
@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[_]
传递该类型的缩小请求。虽然这不是超级优雅但我无法用其他方式表达......
答案 0 :(得分:1)
Play的Java版本通过ThreadLocals可以使用Http.Context
,而Scala版本使用请求。这些可能是隐含的或明确的。
查看您的控制器,当您将Deadbolt添加到某个操作时,您将收到AuthenticatedRequest
。
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
创建实例。