尽我所知,这属于“你不能这样做”。我即将重新思考我的解决方案并解决它,但我认为在这里提问至少值得一试。
我的JSP / Spring / Struts Servlet生成报告,将它们写入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(...)的最终调用对我的客户端没有任何作用。
其他人遇到这个并找到了解决方案吗?
答案 0 :(得分:4)
我所做的是确保在可能的范围内,所有错误都会在 PDF生成开始之前被捕获。这样你就可以发回一套简单的表格错误,或者其他什么。一旦你开始发回这样的附件,浏览器就不会注意其他任何事情了。如果您在生成PDF文件之前绝对找不到错误,我认为您唯一能做的就是将错误消息嵌入到PDF本身中(令人不快,我知道)。
答案 1 :(得分:1)
只需重新排列代码,以便将util
事物向上移动到自己的try-catch块中,并保持响应不变,直到传递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
(不,不是ByteArrayInputStream
)。