导出文件:Faces Servlet抛出java.lang.IllegalStateException:响应提交后无法转发

时间:2011-11-10 10:55:23

标签: jsf

我有一个导出xls文件的方法。该方法正常工作,但在它被执行后,我得到了

  

Faces Servlet抛出java.lang.IllegalStateException:响应提交后无法转发

以下是方法:

public String exportXls() {
    OutputStream out = null;
    try {
        FacesContext cxt = FacesContext.getCurrentInstance();
        ExternalContext context = cxt.getExternalContext();
        HttpServletResponse response = (HttpServletResponse) context.getResponse();
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment; filename=name.xls");
        out = response.getOutputStream();

        WritableWorkbook workbook = createWorkbook(response);

        // All sheets and cells added. Now write out the workbook
        workbook.write();
        workbook.close(); 
        System.out.println("XLS written!");
    } catch(Exception ex) {
        logger.error("ERROR OCCURRED WITH exportXls" + ex.toString());
    } finally {
        try {
            if (out != null) out.close();
        } catch(IOException e) {
            logger.error(e);
            e.printStackTrace();
        }
    }
    return "page";
}

我已关闭OutputStreamWorkbook。您认为这可能是什么问题?

2 个答案:

答案 0 :(得分:0)

一旦内容输出到客户端,您就无法转发(或重定向)。

您尝试做的事情相当于为单个请求获取两个回复 - 您可以返回文件或新页面,但不能同时获取这两个回复。

答案 1 :(得分:0)

您需要通过致电FacesContext#resposneComplete()告诉JSF您已经完成了回复。你也不应该返回一个导航案例字符串(不是它会造成伤害,但这对维护者来说完全是多余的和令人困惑的。)

public void exportXls() {
    // ...

    FacesContext.getCurrentInstance().responseComplete();
}

对于具体问题

无关,我强烈建议删除 catch (Exception ex)块,并将其替换为方法上的throws IOException。所有代码都可以抛出IOException。你不应该吞下那个例外,而是让容器处理它。这也允许Filter进行更集中的异常记录。