在Internet Explorer中通过HTTPS使用ServletOutputStream从Servlet返回CSV文件 [英] Returning CSV file from Servlet using ServletOutputStream over HTTPS in Internet Explorer

查看:134
本文介绍了在Internet Explorer中通过HTTPS使用ServletOutputStream从Servlet返回CSV文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Servlet which is returning a csv file that is 'working' over HTTP in both internet explorer and firefox. When I execute the same Servlet over HTTPS only firefox continues to download the csv file over HTTPS. I don't think this is necessarily an Internet 6 or 7 issue described on MSDN :

消息是:


Internet Explorer无法从
data.csv下载mydomain.com互联网
资源管理器无法打开这个
的互联网站点。请求的网站是
不可用或无法找到。
请稍后再试。

Internet Explorer cannot download data.csv from mydomain.com Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later.

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

Please note that the site is still 'up' after this message and you can continue to browse the site, its just the download of the CSV that prompts this message. I have been able to access similar files over https on IE from other j2ee applications so I believe it is our code. Should we not be closing the bufferedOutputStream?

更新

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

whether to close or not to close the output stream: I asked this question on the java posse forums and the discussion there is also insightful. In the end it seems that no container should rely on the 'client' (your servlet code in this case) to close this output stream. So if your failure to close the stream in your servlet causes a problem it is more a reflection on the poor implementation of your servlet container than your code. I sited the behavior of the IDEs and tutortials from Sun, Oracle and BEA and how they are also inconsistent in whether they close the stream or not.

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

About IE specific behavior: In our case a separate product 'Oracle Web Cache' was introducing the additional header values which impacts Internet explorer only because of the way IE implements the 'No Cache' requirement (see the MSDN article). The code is:

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,那是容器的东西):

I am really confused about your "from back through the breast into the head" write mechanism. Why not simple (the servlet output stream will be bufferend, thats container stuff):

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

也不需要刷新输出流也不需要关闭。

There should also be no need to flush the output stream nor to close.

IE不应解析标题内容区分大小写,但是谁知道:不要来源 fileName 。接下来的问题是编码。 CSV是文本,因此您应该使用 getWriter()或g etOutputStream()并将内容类型设置为例如,text / csv; charset = UTF-8。但是 dao 应该将CSV提供为String而不是byte []。

The header content should not be parsed case sensitive by IE, but who knows: do not camelcase fileName. The next question is the encoding. CSV is text, so you should use getWriter() instead or getOutputStream() and set the content type to "text/csv; charset=UTF-8" for example. But the dao should provide the CSV as String instead of byte[].

servlet代码没有任何内容使用HTTPS,因此协议与服务器端无关。你可以用HTTP希望从localhost测试servlet。

The servlet code has nothing to d with HTTPS, so the protocol does not matter from the server side. You may test the servlet from localhost with HTTP i hope.

你的应用程序中的过滤器怎么样?例如,过滤器可以使用缓存控制来设置HTTP标头(或作为页脚)。

What about filters in your application? A filter may als set an HTTP header (or as footer) with cache-control for example.

这篇关于在Internet Explorer中通过HTTPS使用ServletOutputStream从Servlet返回CSV文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆