播放 2.5 Deadbolt-2 的 @subjectPresentOr 从 Java -> Scala 迁移
Play 2.5 Deadbolt-2's @subjectPresentOr migrating from Java -> Scala
我正在将现有的 Java Play 2.5 应用程序迁移到 Scala 并在视图中发现 main.scala.html
使用以下 deadbolt-2 class subjectPresentOr
:
@subjectPresentOr() {
<ul class="nav navbar-nav navbar-right">
@defining(userProvider.getUser(session())) { user =>
... user is present html
}
} {
... user is NOT present html
}
在将所有控制器和操作迁移到 Scala 之后(并将 deadbolt-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 类型 AuthenticatedRequest[_]
的请求,而是超类类型 play.api.mvc.RequestHeader
的请求,并且它不能与其子类 AuthenticatedRequest[_]
如此隐式匹配。
问题是为什么这首先在 Java 版本中起作用? @subjectPresentOr
的 Java 版本不起作用需要任何隐式请求:)
为了在 Scala 版本中修复它,我将用模式匹配包装 @subjectPresentOr
块以发现隐式请求的动态类型,并且仅当其动态类型为 AuthenticatedRequest[_]
时我才会显示块并明确传递给 @subjectPresentOr
该类型的缩小请求。虽然这不是超级优雅,但我想不出任何其他方式......
Play 的 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
}
接收类型为 AuthenticatedRequest
的 request
。
如果你想将 Request
转换为 AuthenticatedRequest
,因为你正在调用包含 Deadbolt 约束的模板,但你的控制器操作不受约束,你可以使用 WithAuthRequestAction
:
def foo = actionBuilder.WithAuthRequestAction().defaultHandler() { request =>
// request is of type AuthenticatedRequest
}
如果您注入 DeadboltActions
代替 ActionBuilders
,同样适用:
def foo= deadboltActions.SubjectPresent()() { request =>
// request is of type AuthenticatedRequest
}
您也可以使用 new AuthenticatedRequest(request, None)
.
从现有的 Request
中创建 AuthenticatedRequest
的实例,而没有 Subject
我正在将现有的 Java Play 2.5 应用程序迁移到 Scala 并在视图中发现 main.scala.html
使用以下 deadbolt-2 class subjectPresentOr
:
@subjectPresentOr() {
<ul class="nav navbar-nav navbar-right">
@defining(userProvider.getUser(session())) { user =>
... user is present html
}
} {
... user is NOT present html
}
在将所有控制器和操作迁移到 Scala 之后(并将 deadbolt-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 类型 AuthenticatedRequest[_]
的请求,而是超类类型 play.api.mvc.RequestHeader
的请求,并且它不能与其子类 AuthenticatedRequest[_]
如此隐式匹配。
问题是为什么这首先在 Java 版本中起作用? @subjectPresentOr
的 Java 版本不起作用需要任何隐式请求:)
为了在 Scala 版本中修复它,我将用模式匹配包装 @subjectPresentOr
块以发现隐式请求的动态类型,并且仅当其动态类型为 AuthenticatedRequest[_]
时我才会显示块并明确传递给 @subjectPresentOr
该类型的缩小请求。虽然这不是超级优雅,但我想不出任何其他方式......
Play 的 Java 版本有一个 Http.Context
可通过 ThreadLocals 获得,而 Scala 版本使用请求。这些可能是隐含的或明确的。
看看你的控制器,当你将 Deadbolt 添加到一个动作中时,你将收到一个 AuthenticatedRequest
。因此,
def foo = Action { request =>
// request is of type Request
}
将收到类型为 Request
的 request
,而相同的操作受 Deadbolt
def foo = actionBuilder.SubjectPresentAction().defaultHandler() { request =>
// request is of type AuthenticatedRequest
}
接收类型为 AuthenticatedRequest
的 request
。
如果你想将 Request
转换为 AuthenticatedRequest
,因为你正在调用包含 Deadbolt 约束的模板,但你的控制器操作不受约束,你可以使用 WithAuthRequestAction
:
def foo = actionBuilder.WithAuthRequestAction().defaultHandler() { request =>
// request is of type AuthenticatedRequest
}
如果您注入 DeadboltActions
代替 ActionBuilders
,同样适用:
def foo= deadboltActions.SubjectPresent()() { request =>
// request is of type AuthenticatedRequest
}
您也可以使用 new AuthenticatedRequest(request, None)
.
Request
中创建 AuthenticatedRequest
的实例,而没有 Subject