如何在JSF模板中显示数据库中的菜单

时间:2013-01-29 11:16:17

标签: jsf java-ee-6

我想在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文件)时,菜单都会重新加载。

如何为每位用户仅加载一次菜单。

2 个答案:

答案 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,因为您将问题标记为