我在一个简单的应用程序中使用JSF 2.0。我有三个豆子1这是登录是在请求范围内,而其他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的方法。
在登录请求中,我正在创建会话并在会话属性中设置用户详细信息。
现在我面临的问题是
我用user1登录,选择菜单项1,显示相应的数据
我在下一个浏览器窗口用user2登录,选择菜单项1,显示相应的数据
我回到浏览器窗口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>
HTTP会话在浏览器的选项卡之间共享,所以您所经历的是预期的行为。当你在下一个选项卡中登录时,你很可能替换了现有的会话属性。
您也可以在不同的浏览器中尝试它,但不能在同一浏览器的不同选项卡中尝试,以查看它是否像您期望的那样工作。最后,会话是每个用户的构造,应该这样看待。您必须为您的bean定义适当的作用域,以便应用程序按照您的期望运行并获得良好的用户体验。
与您的具体问题无关,使用使用POST请求的命令链接进行纯页面到页面导航被认为是一种不好的做法:您应该使用<h:link>
代替。
而且,在我看来,在JSF 2.0应用程序中使用faces-config.xml单独配置导航规则和声明托管bean有点老派。最后但并非最不重要的一点是,JSP现在是一种过时的视图技术,它已被facelets所取代,因此应该仔细重新考虑使用JSP作为视图技术开发新的应用程序。
<标题>参见:- 如何选择合适的bean作用域;
- JSF 2.0中的通信,bean作用域部分;
- 何时使用h:outputLink而不是h:commandLink?.
您需要有条件地呈现会话用户的菜单,而不是登录结果,例如:
<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视图的标准。