调用ServletOutputStream后转发到JSP
据我所知,这属于“你不能这样做”。我即将重新考虑我的解决方案并解决它,但我认为在这里问至少值得一试。
我的 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(...) 的调用没有执行任何操作。
还有其他人遇到过这个问题并找到了解决方案吗?
As near as I can tell, this falls under a "you can't do that". I'm about to re-think my solution and work around it, but I thought that asking here was worth at least a shot.
My JSP/Spring/Struts Servlet produces reports, writes them to PDF, and queues them for download, then waits for the user to request more reports. The details aren't too important. I stream the PDF to the server with the following function call:
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;
}
}
That's pretty straight-forward. I use the response's ServletOutputStream object to ship my bits. It works well.
However, sometimes I trap some errors that are caused during the generation of the reports. They're informative messages like "There were no orders from account blah-blah-blah". I have a section in my JSP that will catch and display these.
So here's the rub: When I have no report to send, I don't call the above function. But I always call something like:
return mapping.findForward("pullReports");
as the last line in my ActionForward method and the errors appear. However, if I have bits to send via the streamFileToBrowser() function, my eventual call to mapping.findForward does nothing.
A bit of digging tells me that Struts is only able to handle one response to the HttpServletResponse object at a time. I've used it with my call to streamFileToBrowser(), so the eventual call to mapping.findForward(...) does nothing as far as my client is concerned.
Anyone else run into this and found a solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我所做的就是尽可能确保在 PDF 生成开始之前捕获所有错误。这样你就可以发回一组简单的旧表单错误,或者其他什么。一旦您开始发回这样的附件,浏览器就不会关注其他任何事情。如果您在生成 PDF 文件之前绝对找不到错误,我认为您唯一能做的就是将错误消息嵌入到 PDF 本身中(我知道这很不愉快)。
What I've done is to make sure that to the extent that it's possible, all errors get caught before the PDF generation begins. That way you can send back a plain old set of form errors, or whatever. Once you've started sending back an attachment like that, the browser isn't going to pay attention to anything else. If you absolutely can't find errors before you get into generating the PDF file, I think the only thing you can do is to embed the error messages in the PDF itself (unpleasant, I know).
只需重新排列代码,以便将 util 内容移到其自己的 try-catch 块中的前面,并保持响应不变,直到 try 块通过。
请注意,这是占用内存的。如果可以的话,宁愿让
util
东西返回一个InputStream
(不,不是ByteArrayInputStream
)。Just rearrange the code so to move up the
util
thing to front in its own try-catch block and keep the response untouched until the try block is passed.Be aware that this is memory hogging. If you can, rather let the
util
thing return anInputStream
(no, not aByteArrayInputStream
).