Java 调用ServletOutputStream后转发到JSP

Java 调用ServletOutputStream后转发到JSP,java,spring,jsp,struts,Java,Spring,Jsp,Struts,据我所知,这属于一个“你不能那样做”的范畴。我正准备重新思考我的解决方案并解决它,但我认为在这里提问至少值得一试 我的JSP/Spring/StrutsServlet生成报告,将其写入PDF,并将其排队下载,然后等待用户请求更多报告。细节不太重要。我使用以下函数调用将PDF流式传输到服务器: public static void streamFileToBrowser(File docFile, HttpServletResponse response) throws Exception { t

据我所知,这属于一个“你不能那样做”的范畴。我正准备重新思考我的解决方案并解决它,但我认为在这里提问至少值得一试

我的JSP/Spring/StrutsServlet生成报告,将其写入PDF,并将其排队下载,然后等待用户请求更多报告。细节不太重要。我使用以下函数调用将PDF流式传输到服务器:

public static void streamFileToBrowser(File docFile, HttpServletResponse response) throws Exception {
try {
    // return file to user
    // set contextType
    response.setContentType("application/pdf");
    // setting some response headers
    response.setHeader("Expires", "0");
    response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
    response.setHeader("Pragma", "public");
    response.setHeader("Content-Disposition","attachment; filename=" + docFile.getName() );

    ServletOutputStream outs = response.getOutputStream();
    byte[] outputFileBytes = util_getBytesFromFile(docFile.getAbsolutePath());
    response.setContentLength(outputFileBytes.length);
    outs.write(outputFileBytes);    // byte[]
    outs.flush();
    outs.close();
    } catch (Exception e) {
        throw e;
    }
}
这很直截了当。我使用响应的ServletOutputStream对象发送我的位。它工作得很好

但是,有时我会捕获在生成报告过程中导致的一些错误。它们是信息性的信息,好像没有来自帐户的订单之类的。我的JSP中有一个部分将捕获并显示这些内容

问题是:当我没有要发送的报告时,我不会调用上面的函数。但我总是这样称呼:

return mapping.findForward("pullReports");
作为ActionForward方法的最后一行,出现错误。但是,如果我有位要通过streamFileToBrowser函数发送,那么我对mapping.findForward的最终调用将不起任何作用

稍微挖掘一下就知道Struts一次只能处理一个对HttpServletResponse对象的响应。我在调用streamFileToBrowser时使用了它,因此最终调用mapping.findForward。。。对我的当事人来说什么都不做


其他人遇到这种情况并找到了解决方案吗?

我所做的是确保在可能的范围内,在PDF生成开始之前捕获所有错误。这样,您就可以发回一组简单的旧表单错误,或者其他什么。一旦你开始发回这样的附件,浏览器就不会注意其他任何事情了。如果您在生成PDF文件之前绝对找不到错误,我认为您唯一能做的就是将错误消息嵌入PDF本身,我知道。

只需重新排列代码,以便在自己的try-catch块中将util向上移动到前面,并在try块通过之前保持响应不变

byte[] outputFileBytes;

try {
    outputFileBytes = util_getBytesFromFile(docFile.getAbsolutePath());
} catch (Exception e) {
    throw e; // Do the forward call when this is caught in the calling method. If necessary, wrap in a more specific excaption so that you can distinguish what action to take.
}

response.setContentType("application/pdf");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
response.setHeader("Content-Disposition","attachment; filename=" + docFile.getName() );
response.setContentLength(outputFileBytes.length);
ServletOutputStream outs = response.getOutputStream();
outs.write(outputFileBytes);    // byte[]
outs.close();

请注意,这是内存占用。如果可以的话,让util东西返回一个InputStream no,而不是ByteArrayInputStream。

这正是我的方向。然后,错误消息会变成类似“不要这样做”,并要求用户在获取报告之前清除其请求。不完全是我想要的,但它符合我提醒用户为什么他们试图创建的报告中缺少数据的规范。