我有一个Servlet,它返回一个在Internet Explorer和Firefox中通过HTTP“工作”的csv文件。当我通过HTTPS执行相同的Servlet时,只有firefox继续通过HTTPS下载csv文件。我认为这不一定是on MSDN所述的互联网6或7问题:
消息是:
Internet Explorer无法下载 来自mydomain.com Internet的data.csv 资源管理器无法打开它 互联网网站。请求的网站是 要么不可用,要么找不到。 请稍后再试。
请注意,此消息后该网站仍处于“启动”状态,您可以继续浏览该网站,只需下载提示此消息的CSV即可。我已经能够通过IE浏览器从其他j2ee应用程序访问类似的文件,所以我相信这是我们的代码。 我们不应该关闭bufferedOutputStream吗?
更新
是否关闭输出流: 我在java团队论坛上问了这个问题,discussion也有见解。最后,似乎没有容器应该依赖'client'(在这种情况下是你的servlet代码)来关闭这个输出流。因此,如果未能关闭servlet中的流导致问题,则更多地反映了servlet容器的不良实现,而不是代码。我选择了来自Sun,Oracle和BEA的IDE和tortortials的行为,以及它们是否在关闭流时也不一致。
关于IE特定行为:在我们的案例中,单独的产品“Oracle Web Cache”引入了影响Internet Explorer的额外标头值,因为IE实现了“No Cache”要求的方式( see the MSDN article)。 代码是:
public class DownloadServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
ServletOutputStream out = null;
ByteArrayInputStream byteArrayInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
response.setContentType("text/csv");
String disposition = "attachment; fileName=data.csv";
response.setHeader("Content-Disposition", disposition);
out = response.getOutputStream();
byte[] blobData = dao.getCSV();
//setup the input as the blob to write out to the client
byteArrayInputStream = new ByteArrayInputStream(blobData);
bufferedOutputStream = new BufferedOutputStream(out);
int length = blobData.length;
response.setContentLength(length);
//byte[] buff = new byte[length];
byte[] buff = new byte[(1024 * 1024) * 2];
//now lets shove the data down
int bytesRead;
// Simple read/write loop.
while (-1 !=
(bytesRead = byteArrayInputStream.read(buff, 0, buff.length))) {
bufferedOutputStream.write(buff, 0, bytesRead);
}
out.flush();
out.close();
} catch (Exception e) {
System.err.println(e); throw e;
} finally {
if (out != null)
out.close();
if (byteArrayInputStream != null) {
byteArrayInputStream.close();
}
if (bufferedOutputStream != null) {
bufferedOutputStream.close();
}
}
}
答案 0 :(得分:5)
我真的很困惑你的“从背部通过乳房到头部”的写作机制。为什么不简单(servlet输出流将是bufferend,即容器内容):
byte[] csv = dao.getCSV();
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=data.csv"));
reponse.setContentLength(csv.length);
ServletOutputStream out = response.getOutputStream();
out.write(csv);
也不需要刷新输出流也不需要关闭。
标题内容不应该被IE解析为区分大小写,但是谁知道:不要来源fileName
。接下来的问题是编码。 CSV是文本,因此您应该使用getWriter(
)或g etOutputStream()
并将内容类型设置为“text / csv; charset = UTF-8”。但是dao
应该将CSV提供为String而不是byte []。
servlet代码与HTTPS无关,因此协议与服务器端无关。您可以使用HTTP希望从localhost测试servlet。
您的应用中的过滤器怎么样?例如,过滤器可以使用缓存控制来设置HTTP标头(或作为页脚)。