我的应用程序正在创建一个大型csv文件(它是一个报告),其目的是提供csv文件的内容而不实际为其保存文件。这是我的代码
String csvData; //this is the string that contains the csv contents
byte[] csvContents = csvData.getBytes();
response.contentType = "text/csv";
response.headers.put("Content-Disposition", new Header(
"Content-Disposition", "attachment;" + "test.csv"));
response.headers.put("Cache-Control", new Header("Cache-Control",
"max-age=0"));
response.out.write(csvContents);
ok();
正在生成的csv文件相当大,我得到的错误是
org.jboss.netty.handler.codec.frame.TooLongFrameException:HTTP行大于4096字节。
解决这个问题的最佳方法是什么?
我的技术堆栈是带有播放框架1.2.5的java 6。
注意:响应对象的来源是play.mvc.Controller.response
答案 0 :(得分:1)
请使用
ServletOutputStream的
像
String csvData; //this is the string that contains the csv contents
byte[] csvContents = csvData.getBytes();
ServletOutputStream sos = response.getOutputStream();
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=test.csv");
sos.write(csvContents);
答案 1 :(得分:1)
我们使用它直接在浏览器中显示操作的结果,
window.location='data:text/csv;charset=utf8,' + encodeURIComponent(your-csv-data);
我不确定内存不足错误但我至少会尝试这个:
request.format = "csv";
renderBinary(new ByteArrayInputStream(csvContents));
答案 2 :(得分:0)
显然netty抱怨http-header太长了 - 也许它以某种方式认为你的文件是标题的一部分,另见
http://lists.jboss.org/pipermail/netty-users/2010-November/003596.html
正如nylund所述,使用renderBinary应该可以解决问题。
我们使用writeChunk oursleves即时输出大型报告,如:
控制器:
public static void getReport() {
final Report report = new Report(code, from, to );
try {
while (report.hasMoreData()) {
final String data = await(report.getData());
response.writeChunk(data);
}
} catch (final Exception e) {
final Throwable cause = e.getCause();
if (cause != null && cause.getMessage().contains("HTTP output stream closed")) {
logger.warn(e, "user cancelled download");
} else {
logger.error(e, "error retrieving data");
}
}
}
报告代码中的
public class Report {
public Report(final String code, final Date from, final Date to) {
}
public boolean hasMoreData() {
// find out if there is more data
}
public Future<String> getData() {
final Job<String> queryJob = new Job<String>() {
@Override
public String doJobWithResult() throws Exception {
// grab data (e.g read form db) and return it
return data;
}
};
return queryJob.now();
}
}