0

我想在 JSF 模板中显示菜单。我的应用程序的每个用户都有不同的菜单,菜单存储在数据库中。这是我的代码,

MenuBean.java

public List<Menuitem> getUserMenu() {
    List<Menuitem> menuitems = (List<Menuitem>) em.createQuery("_____________").setParameter("_______", _______).getResultList();
    return menuitems;
}

页面模板.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 文件)时,菜单都会重新加载。

如何每个用户只加载一次菜单。

4

2 回答 2

4

如果菜单依赖于用户,最好创建一个 bean,其作用域session将存储此菜单的内容。这样,一旦菜单第一次初始化,就不会重新初始化。您的代码将如下所示:

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 调用服务以检索构建菜单项所需的信息。

于 2013-01-29T11:27:39.537 回答
2

您不应该将访问数据库的逻辑放在 getter 方法中,因为它们通常在同一个 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,因为您将问题标记为

于 2013-01-29T11:28:33.860 回答