1

我正在将现有的 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 -> Scala 更改 deadbolt-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 版本中有效?Java 版本@subjectPresentOr不需要任何隐式请求 :)

为了在 Scala 版本中修复它,我将@subjectPresentOr使用模式匹配包装块以发现隐式请求的动态类型,并且只有当它的动态类型是AuthenticatedRequest[_]我才会显示块并显式传递给@subjectPresentOr该类型的缩小请求。虽然这不是超级优雅,但我想不出任何其他方式......

4

1 回答 1

1

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

查看您的控制器,当您将 Deadbolt 添加到操作时,您将收到一个AuthenticatedRequest. 所以,一个非死锁动作

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

将收到 arequest类型Request,而相同的动作受 Deadbolt 保护

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

接收request类型AuthenticatedRequest

如果您想将 a 转换Request为 an,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
}

您也可以只使用现有AuthenticatedRequestRequest和 no创建一个实例。Subjectnew AuthenticatedRequest(request, None)

于 2016-12-16T08:56:22.927 回答