Java Play 框架创建登录导航栏 - 在 scala 模板中插入动态 html



我正在使用Java中的Play Framework,使用OAuth和Bootstrap创建简单的网站。我的目标是让导航栏在身份验证后显示登录用户 - 所以我需要动态创建导航栏的 html 代码。许多人会立即建议使用 scala 模板参数来创建动态内容:

导航.斯卡拉.html

@(loggedInUser: String)
<div class="navbar">
<div class="containter">
<ul class="nav navbar-nav navbar-left">
<li>Logged in as: @loggedInUser</li>
</ul>
</div>
</div>

主斯卡拉.html

@(loggedInUser: String)(content: Html)
<!DOCTYPE html>
<html lang="en">
<body>
@navigation(loggedInUser)
@content    
</body>
</html>

这似乎很好,但随着应用程序的增长,将会有更多的模板必须调用主模板,并且在每一个模板中,我将传递参数loggedInUser,以便它到达导航。它只是成为每个模板上的一大堆参数。那么有没有办法直接获取这个 loggedInUser 字符串,而不是通过调用的模板传递它?我试图通过将静态控制器作为实用程序来解决它,这将获取我的用户名,我将通过在授权时将用户名放在会话属性中,然后用"实用程序控制器"拉动它来做到这一点:

public class UsernameController extends Controller {
public static String getLoggedInUsername() {
return ctx().session().get("username");
}
}

然后将navigation.scala.html更改为:

@()
<div class="navbar">
<div class="containter">
<ul class="nav navbar-nav navbar-left">
<li>Logged in as: "@routes.UsernameController.getLoggedInUsername()"</li>
</ul>
</div>
</div>

但这也不能很好地工作,因为控制器是静态的,例如,当涉及到工厂类的依赖注入(在我的情况下使用 pac4j 进行 OAuth)时,你不能使用静态方法(我知道有静态注入解决方案,但不建议使用)。我希望有某种方法可以在生成 html 的 scala 模板中使用方法,以便我可以使用它将其注入 navigation.scala.html(方法可以访问会话和所有属性,以便我可以获取有关当前用户的信息)

您可以使用Deadbolt 来处理此问题,使用@subjectPresent和/或@subjectPresentOr模板约束。 前者只允许在用户登录时进行渲染,而后者在没有用户登录的情况下呈现替代内容,例如

@import be.objectify.deadbolt.java.views.html.{subjectPresent, subjectPresentOr}
@subjectPresent() {
This content will be present if handler#getSubject results in a Some 
}
@subjectPresentOr() {
This content will be present if handler#getSubject results in a Some 
} {
fallback content
}

查看 Deadbolt Java 文档以获取更多详细信息。

但是,如果您需要在模板中显示用户详细信息,那么您确实应该将该信息传递到模板中。

使用<li>Logged in as: "@routes.UsernameController.getLoggedInUsername()"</li>是一种不干净的方法,很可能不是线程安全的。 Twirl 模板是类型安全的,参数化是有原因的!

最新更新