@PostConstruct中的重定向导致IllegalStateException

su9*_*bsa 12 jsf jsf-2

我想在我的4个支持bean中的@PostConstruct中进行重定向.正如我从以下问题中学到的: JSF PostConstruct异常处理 - 重定向 我知道我应该使用:

    @PostConstruct
    public void init() {    
       if (shouldRedirect) {
          try { 
             FacesContext.getCurrentInstance().getExternalContext().redirect("bolagsSok_company.xhtml");
             return;
          } catch (IOException e) {
             //do nothing
          }
        }
        ....
     }
Run Code Online (Sandbox Code Playgroud)

这适用于我的2个Backing bean ...但是对于其他两个,非重定向的xhtml文件仍然调用支持bean而不重定向.我已经确认(使用调试),支持bean确实调用了两个FacesContext.getCurrentInstance().getExternalContext().redirect("bolagsSok_company.xhtml");并返回; 声明.

有什么线索可能是错的?

Bal*_*usC 24

@PostConstruct如果响应已经提交,则重定向可能为时已晚.即,当响应的前几个字节已经发送到客户端时.这是一个不归路.在你的情况下,可以在视图中相对较晚的时候第一次引用(并因此构造)支持bean时发生,可能是大约一半或最后.

您可以通过以下方式之一解决此问题:

  1. 在视图中尽早引用bean第一次.

  2. <f:event type="preRenderView">而不是@PostConstruct.这将在渲染响应开始之前调用该方法(因此,在将任何位发送到响应之前).或者,当您使用JSF 2.2时,请使用<f:viewAction>.另外一个优点是<f:viewAction>可以返回导航案例结果,return bolagsSok_company?faces-redirect=true"而无需操作ExternalContext#redirect().

  3. 通过javax.faces.FACELETS_BUFFER_SIZE上下文参数将默认的Facelets缓冲区大小web.xml增加到大约最大HTML响应的大小.

也可以看看:

  • `&lt;f:metadata&gt;` 必须放在顶层视图(模板客户端)中,而不是放在模板文件(主模板)中。另请参阅 [标签文档](http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/metadata.html)。但是,`&lt;f:event&gt;` 不一定需要放在 `&lt;f:metadata&gt;` 中。只需将它放在外面并去掉`&lt;f:metadata&gt;`(请注意,我的答案中没有提到使用`&lt;f:metadata&gt;`...)。另见 http://stackoverflow.com/questions/7343220/jsf-does-it-matter-whether-place-fevent-inside-fmetadata-or-not (2认同)