Redirect @PostConstruct方法中的重定向导致IllegalStateException
根据调查,我使用了 在我的Redirect @PostConstruct方法中的重定向导致IllegalStateException,redirect,jsf-2,illegalstateexception,Redirect,Jsf 2,Illegalstateexception,根据调查,我使用了 在我的@PostConstruct方法中,停止JSF呈现视图并重定向用户。然而,当我试图运行代码时,我仍然在上面的一行遇到了java.lang.IllegalStateException异常 WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception java.lang.IllegalStateExcepti
@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
方法之前提交
如果您能给我一个建议,我将不胜感激。重定向在这里不起作用,因为即使响应已经完成并最终确定,JSF也没有足够的智能来避免其典型的运行生命周期事件的例行程序 相反,您可以尝试从RequestDispatcher执行转发。转发与重定向的不同之处在于:
- 由servlet在内部执行
- 浏览器是冷漠的
- 原始url保持不变
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可以重定向到所需的位置。正如我在更新中提到的,下面一行打印了
INIT true
:
System.out.println("INIT " + FacesContext.getCurrentInstance().getExternalContext().isResponseCommitted());
我终于找到了发生上述情况的原因。在我的页面上,在
UIComponent A
引用包含重定向功能的ManagedBean X
之前,页面结构中位于UIComponent A
上方的UIComponent B
预先引用了另一个managedbeany
。因此,响应部分由managedbeany
提交,这使得managedbeanx
无法发送重定向
请求。我非常确定,即使响应在构建后完成,JSF生命周期的其余部分仍将执行。你会从构造函数那里得到一个错误吗?这是Ajax请求吗?您使用的是什么JSF实现和版本?我使用的是JSF2.0。此外,我必须在@PostConstruct
中执行此操作,因为我需要在重定向之前从EJB调用函数。它也不是一个AJAX请求。响应是提交的,因为响应头已经被FacesServlet操作过了。这与正在完成的响应不同,这意味着主体已经写入并最终确定,直到渲染阶段才会发生。在响应提交后的任何时候重定向都会导致IllegalStateException,因此您唯一的选择是转发。这在中得到了正确的解决:(这是实现我想要的目标的唯一方法吗?创建一个新servlet对于我需要的简单重定向来说似乎有点太多了。)。
System.out.println("INIT " + FacesContext.getCurrentInstance().getExternalContext().isResponseCommitted());