没有内容长度的响应附件无法在浏览器中打开(IE、FF)
Response Attachment without Content Length won't open in browser (IE,FF)
我有一个生成 csv
报告并将其作为附件发送到客户端(浏览器)的 servlet。
下面是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) 后不再弹出 open/save 附件的对话框。
我的印象是建议设置内容长度,但不是强制性的。
那么为什么上面的代码不正确呢?
事实证明,此行为是由以下行引起的:
response.setHeader("Content-disposition","filename=\""+fileName+"");
原因是缺少结尾引号
response.setHeader("Content-disposition","filename=\""+fileName+"\"");
我有一个生成 csv
报告并将其作为附件发送到客户端(浏览器)的 servlet。
下面是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) 后不再弹出 open/save 附件的对话框。
我的印象是建议设置内容长度,但不是强制性的。
那么为什么上面的代码不正确呢?
事实证明,此行为是由以下行引起的:
response.setHeader("Content-disposition","filename=\""+fileName+"");
原因是缺少结尾引号
response.setHeader("Content-disposition","filename=\""+fileName+"\"");