我有以下JSF支持bean方法,它应该根据某些条件执行重定向。
public void navigationStatus() throws IOException {
log(LogMessages.getLogString(user, currentDatasource, nomeClasse, "navigationStatus", "navigationStatus"), null);
logger.debug("INSIDE navigationStatus ");
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
if (!isUserEnabled()) {
log(LogMessages.getLogString(user, currentDatasource, nomeClasse, "navigationStatus", "Sessione utente SCADUTA"), null);
logger.debug("Sessione utente SCADUTA");
response.sendRedirect("error.jsp");
}
}
但这并不是在所有页面上都有效。它可以在某些页面上工作,但不能在其他页面上工作。这是如何造成的,我该如何解决? 在下列情况下,这肯定会失败:
- HTTP请求是ajax请求。
- HTTP响应已经提交。
要解决/避免它们,您需要:
-
使用标准的JSF API方法来发送重定向,而不是从JSF的框架下拖出原始的Servlet API,后者反过来对它所运行的JSF上下文一无所知。
context.getExternalContext().redirect("error.jsp");
那么传入的HTTP请求是一个ajax请求,那么上述方法将透明地返回JSF ajax引擎所期望的正确的XML响应。
将来,当您需要从JSF支持bean中的
javax.servlet.*
包中导入一些东西时,您应该立即停止编码,并问自己是否真的没有一种标准的JSF方法来完成您所想到的工作。 -
在呈现响应阶段之前执行作业。如果你在请求/视图作用域支持bean的构造函数或
@PostConstruct
中这样做,它第一次被引用是在页面的"中途",那么发送重定向可能为时已晚,因为HTTP响应的第一部分已经被发送到客户端。这是一个不归路,你只会得到IllegalStateException
在服务器日志的所有地方。如果确实是这种情况,那么您需要通过侦听
preRenderView
的<f:event>
调用该作业。<f:event type="preRenderView" listener="#{bean.navigationStatus}" />