Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Redirect @PostConstruct方法中的重定向导致IllegalStateException_Redirect_Jsf 2_Illegalstateexception - Fatal编程技术网

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());