在Internet Explorer中通过HTTPS使用ServletOutputStream从Servlet返回CSV文件

我有一个Servlet,它返回一个在Internet Explorer和Firefox中通过HTTP“工作”的csv文件。 当我通过HTTPS执行相同的Servlet时,只有firefox继续通过HTTPS下载csv文件。 我认为这不一定是MSDN上描述的Internet 6或7问题:

消息是:

Internet Explorer无法从mydomain.com下载data.csv Internet Explorer无法打开此Internet站点。 请求的网站不可用或无法找到。 请稍后再试。

请注意,此消息后该网站仍处于“启动”状态,您可以继续浏览该网站,只需下载提示此消息的CSV即可。 我已经能够通过IE浏览器从其他j2ee应用程序访问类似的文件,所以我相信这是我们的代码。 我们不应该关闭bufferedOutputStream吗?

UPDATE

是关闭还是不关闭输出流:我在java团队论坛上问了这个问题, 讨论也很有见地。 最后似乎没有容器应该依赖’client’(在这种情况下是你的servlet代码)来关闭这个输出流。 因此,如果您无法关闭servlet中的流导致问题,那么它更多地反映了servlet容器的不良实现,而不是代码。 我选择了来自Sun,Oracle和BEA的IDE和tortortials的行为,以及它们是否在关闭流时也不一致。

关于IE特定行为 :在我们的案例中,单独的产品“Oracle Web Cache”引入了影响Internet Explorer的额外标头值,因为IE实现了“无缓存”要求的方式( 请参阅MSDN文章 )。 代码是:

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(); } } } 

我真的很困惑你的“从背部通过乳房到头部”的写机制。 为什么不简单(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解析为区分大小写,但是谁知道:不要使用camelcase fileName 。 接下来的问题是编码。 CSV是文本,因此您应该使用getWriter( )或g etOutputStream()并将内容类型设置为“text / csv; charset = UTF-8”。 但dao应该将CSV提供为String而不是byte []。

servlet代码与HTTPS无关,因此协议与服务器端无关。 您可以使用HTTP测试来自localhost的servlet。

您的应用中的filter怎么样? 例如,filter可以设置具有高速缓存控制的HTTP标头(或作为页脚)。