在backing bean方法中调用HttpServletResponse#sendRedirect()不适用于所有页面

时间:2013-03-26 12:17:29

标签: jsf redirect

我有以下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");         
    }
}

然而,这不适用于所有页面。它适用于某些页面,但不适用于其他页面。这是怎么造成的,我该如何解决?

1 个答案:

答案 0 :(得分:0)

在以下情况下,这肯定会失败:

  1. 传入的HTTP请求是ajax请求。
  2. HTTP响应已提交。
  3. 要解决/避免它们,您需要:

    1. 使用标准的JSF API方法发送重定向,而不是从JSF的引擎下运送原始的Servlet API,后者又不知道它正在运行的JSF上下文。

      context.getExternalContext().redirect("error.jsp");
      

      然后传入的HTTP请求是一个ajax请求,然后上面的方法将透明地返回JSF ajax引擎所期望的正确的XML响应。

      将来,只要你需要从JSF支持bean中的javax.servlet.*包中导入一些东西,那么你应该立即停止编码并问自己是否真的没有一种标准的JSF方式来完成你所拥有的工作。心。

    2. 在渲染响应阶段之前执行作业。如果你是这样做的,例如第一次引用关于页面“中途”的请求/视图作用域支持bean的构造函数或@PostConstruct,然后发送重定向可能为时已晚,因为HTTP响应的第一部分是已经被发送到客户端。这是一个不归路的点,您只能在服务器日志中获得IllegalStateException

      如果确实如此,则需要<f:event>监听preRenderView来调用作业。

      <f:event type="preRenderView" listener="#{bean.navigationStatus}" />