我想在JSF模板中显示菜单。我的应用程序的每个用户都有不同的菜单,菜单存储在数据库中。这是我的代码,
MenuBean.java
public List<Menuitem> getUserMenu() {
List<Menuitem> menuitems = (List<Menuitem>) em.createQuery("_____________").setParameter("_______", _______).getResultList();
return menuitems;
}
pageTemplate.xhtml
<div class="container">
<div id="navigation">
<ul>
<ui:repeat var="_item" value="#{menuitemBean.userMenu}">
<li><h:outputLink value="#{_item.url}">
<h:outputText value="#{_item.name}" />
</h:outputLink></li>
</ui:repeat>
</ul>
</div>
<div id="content">
<h1>
<ui:insert name="header" />
</h1>
<h2>
<ui:insert name="subheader" />
</h2>
<ui:insert name="main" />
</div>
</div>
问题是每次我导航到使用相同模板(pageTemplate.xhtml)的新页面(.xhtml文件)时,菜单都会重新加载。
如何为每位用户仅加载一次菜单。
答案 0 :(得分:4)
如果菜单依赖于用户,最好创建一个范围为session
的bean来存储此菜单的内容。
这样,一旦菜单第一次初始化,就不会重新初始化。您的代码将如下所示:
public class MySessionBean ... {
private List<Menuitem> menuItems = null;
public List<Menuitem> getUserMenu() {
if (menuItems == null) {
// Initialize the menu items.
menuItems = ...;
}
return menuitems;
}
请注意,您还可以在构造函数中或menuItems
方法中初始化post-construct
对象(即在实例化bean之后调用的方法)。
还有一件重要的事情:不要将数据库访问代码放在您的bean中(您的em.createQuery(...)
)。在服务/ DAO层上移动它,让bean调用服务来检索构建菜单项所需的信息。
答案 1 :(得分:2)
你应该 NOT 将逻辑访问数据库放入getter方法,因为they are often called more than once in the same request。
要为每个用户加载一次菜单,请将该属性放在@SessionScoped
支持bean中,然后使用@PostConstruct
带注释的方法对其进行初始化:
@SessionScoped
public SomeBean {
private List<Menuitem> menuItems;
@PostConstruct
public void init() {
menuItems = (List<Menuitem>) em.createQuery("_____________")
.setParameter("_______", _______).getResultList();
}
// getter and setter for menuItems
}
由于bean在会话范围内,它将作为应用程序中每个用户会话的一个实例存在。
请注意,我假设您使用的是JSF 2,因为您将问题标记为java-ee-6。