Java 没有内容长度的响应附件赢得';无法在浏览器中打开(即,FF)

Java 没有内容长度的响应附件赢得';无法在浏览器中打开(即,FF),java,servlets,jasper-reports,Java,Servlets,Jasper Reports,我有一个servlet,它生成csv报告并将其作为附件发送到客户端(浏览器) 下面是servlet的代码部分: private void generateCSVOutput( HttpServletResponse response, java.util.Map parameters, JasperPrint jasperPrint) throws JRException, NamingException, SQLExcep

我有一个servlet,它生成
csv
报告并将其作为附件发送到客户端(浏览器)

下面是servlet的代码部分:

private void generateCSVOutput(
            HttpServletResponse response,
            java.util.Map parameters,
            JasperPrint jasperPrint) throws JRException, NamingException, SQLException, IOException {
            String fileName = makeFileName(parameters, ".csv");
            response.setHeader("Content-disposition","filename=\""+fileName+"");
            byte[] bytes = null;
            JRCsvExporter exporter = new JRCsvExporter();
            ByteArrayOutputStream csvReport = new ByteArrayOutputStream();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, csvReport);
            exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "sample.csv");
            exporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, ";");
            exporter.exportReport();
            bytes = csvReport.toByteArray();
            response.setContentType(getMimeType("csv"));
            response.setContentLength(bytes.length);
            ServletOutputStream ouputStream = response.getOutputStream();
            ouputStream.write(bytes, 0, bytes.length);
            ouputStream.flush();
            ouputStream.close();

    }
现在,为了避免内存消耗,我决定将报告的输出直接流式传输到响应 避免使用
ByteArrayOutputStream

副作用是我不再有关于内容长度的信息。 因此未设置内容长度。生成的代码是:

private void generateCSVOutput(
            HttpServletResponse response,
            java.util.Map parameters,
            JasperPrint jasperPrint) throws JRException, NamingException, SQLException, IOException {
            String fileName = makeFileName(parameters, ".csv");
            response.setHeader("Content-disposition","filename=\""+fileName+"");
            JRCsvExporter exporter = new JRCsvExporter();
            //ByteArrayOutputStream csvReport = new ByteArrayOutputStream();
            ServletOutputStream ouputStream = response.getOutputStream();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream);
            exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "sample.csv");
            exporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, ";");
            exporter.exportReport();
            //bytes = csvReport.toByteArray();
            response.setContentType(getMimeType("csv"));
            //response.setContentLength(bytes.length);
            //ServletOutputStream ouputStream = response.getOutputStream();
            //ouputStream.write(bytes, 0, bytes.length);
            ouputStream.flush();
            ouputStream.close();

    }
但是,更改后,浏览器(IE、FF)不再弹出打开/保存附件的对话框

我的印象是,设置内容长度是建议的,但不是强制性的


那么,为什么上面的代码行为不正确呢?

结果表明,这种行为是由以下行引起的:

response.setHeader("Content-disposition","filename=\""+fileName+"");
原因是缺少结尾引用

response.setHeader("Content-disposition","filename=\""+fileName+"\"");