根据answer of BalusC,我使用了
FacesContext.getCurrentInstance().getExternalContext().redirect(url);
在我的@PostConstruct
方法中阻止JSF呈现视图并重定向用户。但是,当我尝试运行代码时,我仍然遇到上述行的java.lang.IllegalStateException
异常。
WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:524)
at StudentManagedBean.CourseSummary.init(CourseSummary.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
更新:我在@PostConstruct
方法中添加了以下行:
System.out.println("INIT " + FacesContext.getCurrentInstance().getExternalContext().isResponseCommitted());
我看到的是INIT true
。我想知道在调用@PostConstruct
方法之前是否应该提交响应?
如果你能给我一个建议,我将非常感激。
答案 0 :(得分:3)
正如我的更新中所述,以下行打印了INIT true
:
System.out.println("INIT " + FacesContext.getCurrentInstance().getExternalContext().isResponseCommitted());
我终于找到了上述情况发生的原因。在我的网页上,在ManagedBean X
(包含重定向功能)之前,UIComponent A
引用了另一个ManagedBean Y
,之前UIComponent B
引用了UIComponent A
,ManagedBean Y
位于ManagedBean X
之上在页面结构中。因此,redirect
部分提交了回复,这使得{{1}}无法发送{{1}}请求。
答案 1 :(得分:2)
重定向在这里不起作用,因为即使响应已经完成并最终确定,JSF也不够智能,无法避免其通过生命周期事件的典型例程。
相反,您可以尝试从RequestDispatcher执行转发。转发与以下方式的重定向不同:
以下是一些显示如何完成此操作的代码...
RequestDispatcher dispatcher =
((ServletRequest) context.getExternalContext().getRequest())
.getRequestDispatcher("/j_spring_security_logout");
try {
dispatcher.forward((ServletRequest) context.getExternalContext().getRequest(),
(ServletResponse) context.getExternalContext().getResponse());
} catch (ServletException e) {
log.error("ServletException", e);
} catch (IOException e) {
log.error("IOException", e);
}
通过执行此操作,您将过早地结束FacesServlet的执行并将其转发到另一个servlet上。我想,从这个其他servlet可以重定向到所需的位置。