1

我在一个简单的应用程序中使用 JSF 2.0。我有三个 bean 第一个是登录在请求范围内,而其他 2 在视图范围内。我已经在 faces-config.xml 中进行了配置。

<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
 <navigation-rule>
        <from-view-id>*</from-view-id>
        <navigation-case>
            <from-outcome>loginSuccess</from-outcome>
            <to-view-id>/pages/ReportSubmit.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
            <from-outcome>reportStatus</from-outcome>
            <to-view-id>/pages/ReportStatus.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
            <from-outcome>logout</from-outcome>
            <to-view-id>/pages/logout.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
    <managed-bean>
        <managed-bean-name>UserBean</managed-bean-name>
        <managed-bean-class>com.cognizant.reportgen.LoginBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>

    <managed-bean>
        <managed-bean-name>ReportBean</managed-bean-name>
        <managed-bean-class>com.cognizant.reportgen.ReportGeneratorBean</managed-bean-class>
        <managed-bean-scope>view</managed-bean-scope>
    </managed-bean>

    <managed-bean>
        <managed-bean-name>ReportStatus</managed-bean-name>
        <managed-bean-class>com.cognizant.reportgen.ReportStatusBean</managed-bean-class>
        <managed-bean-scope>view</managed-bean-scope>
    </managed-bean>

</faces-config>

我有一个 menu.jsp 有以下代码

menu item1 <h:commandLink action="loginSuccess" value="Generate Reports"></h:commandLink>
menu item 2<h:commandLink action="reportStatus" value="Report Status"></h:commandLink>

在 2 个 bean 中,我有返回类型为 void 的方法。

在登录请求中,我正在创建会话并在会话属性中设置用户详细信息。

现在我面临的问题是

  1. 我用user1登录,选择菜单项1,显示相应的数据。

  2. 我在下一个浏览器窗口中使用 user2 登录,选择菜单项 1,显示相应的数据。

  3. 我回到浏览器窗口 1(user1),再次选择菜单项 1,但现在在标题中显示 user2 名称。,它还显示与 user2 对应的数据。

请帮我解决这个问题。

//ReportStatusBean.java
public class ReportStatusBean {
    private List<ReportAttrDO> reportList;
    private HtmlDataTable reportStatusTable;
    // getters and setter for above included....
    public void checkReportStatus(ActionEvent event) {

        ReportGenService reportGenObj = new ReportGenServiceImpl();
        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
        UserDetail user = (UserDetail)session.getAttribute("user");
        List<ReportAttrDO> reportList = reportGenObj.getReportStatusList(user.getUserId());
        setReportList(reportList);
        if(reportList.isEmpty())
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "No Records to display.", null));
    }

    public void viewReport(ActionEvent event) {
        ReportAttrDO reportAttrDO = (ReportAttrDO)getReportStatusTable().getRowData();
        System.out.println(reportAttrDO.getRequestHeaderId());
    }

}

// ReportStatus.jsp
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<f:view>
<html>
<head>
....some script functions..
</head>
<body onload="noBack();" onpageshow="if (event.persisted) noBack();" onunload="">

<center>
    <div class="wrapper">
    <%@include file="../include/pageheader.jsp"%>
    <%@include file="../include/menu.jsp"%>
    <h:form id="form2">
    <table border="0">
    <tr>
            <td colspan="2"><h:messages style="color:red;margin:8px;" /></td>
        </tr>
        <tr>
            <td colspan="2"><h:commandButton value="Check Status" actionListener="#{ReportStatus.checkReportStatus}" /></td>
        </tr>
    </table>
                <c:if test="${not empty ReportStatus.reportList}" >
                <div style="height:200px;width:600px;overflow:auto;">

                <h:dataTable id="table" border="1"
                    var="row" value="#{ReportStatus.reportList}" cellpadding="5" cellspacing="5"
                    binding="#{ReportStatus.reportStatusTable}">

                    <h:column>
                        <f:facet name="header">
                            <f:verbatim>
                                <h:outputText value="Application Name" />
                            </f:verbatim>
                        </f:facet>
                        <h:outputText id="applName" value="#{row.applicationName}" ></h:outputText>

                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <f:verbatim>
                                <h:outputText value="Report Name" />
                            </f:verbatim>
                        </f:facet>
                        <h:outputText id="reportReqName" value="#{row.reportRequestName}"></h:outputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <f:verbatim>
                                <h:outputText value="Generated Report" />
                            </f:verbatim>
                        </f:facet>
                        <h:commandLink id="viewReport" value="View" rendered="#{row.status == 'Completed'}" actionListener="#{ReportStatus.viewReport}"></h:commandLink>
                    </h:column>
                </h:dataTable>
                </div>
                </c:if>
    </h:form>
    </div>
</center>
</body>
</html>
</f:view>
4

2 回答 2

1

HTTP 会话在浏览器的选项卡之间共享,因此您遇到的是预期行为。当您在下一个选项卡中登录时,您很可能替换了现有的会话属性。

您也可以在不同的浏览器中尝试它,但不能在同一浏览器的不同选项卡中尝试,以查看它是否按预期工作。最后,会话是每个用户的构造,应该这样看待。您必须为 bean 定义适当的范围,以便应用程序按照您的期望运行并获得良好的用户体验。

与您的具体问题无关,使用使用 POST 请求进行普通页面到页面导航的命令链接被认为是一种不好的做法:您应该<h:link>改用。有关详细信息,请参阅下面的第三个参考。

此外,在我看来,在 JSF 2.0 应用程序中使用 faces-config.xml 单独配置导航规则和声明托管 bean 有点过时。最后但并非最不重要的一点是,JSP 是如今已被弃用的视图技术,已被 facelets 所取代,因此应仔细重新考虑使用 JSP 作为视图技术开发新应用程序。

也可以看看:

  1. 如何选择合适的bean范围?;
  2. JSF 2.0 中的通信,关于 bean 范围的部分
  3. 什么时候应该使用 h:outputLink 而不是 h:commandLink?.
于 2013-04-14T14:11:43.020 回答
0

您需要根据会话用户而不是登录结果呈现菜单条件,例如:

<h:form>
    <h:panelGroup rendered="#{not userbean.isLogged}">
        <h:inputText value="#{userBean.username}" />
        <h:inputText value="#{userBean.password}" />
        <h:commandButton actionListener="#{userBean.login}" />
    </h:panelGroup>

    <h:panelGroup rendered="#{userBean.isLogged}">
        <h:commandLink rendered="#{userBean.user eq "user1"}" action="loginSuccess" value="Generate Reports"></h:commandLink>
        <h:commandLink rendered="#{userBean.user eq "user2"}" action="reportStatus" value="Report Status"></h:commandLink>
    </h:panelGroup>
</h:form>

当然,例如,它需要 userBean 内部的一些函数来获取用户名。

另外,您的意思是您已经使用ViewScoped配置了 bean ,它们在提供的代码中都是RequestScoped

我建议您使用 .xhtml 文件扩展名,这是 JavaServer Faces 视图中的标准。

于 2013-04-14T13:42:25.677 回答