通过浏览器传递csv文件时出错

时间:2012-11-10 00:13:26

标签: java csv playframework download playframework-1.x

我的应用程序正在创建一个大型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

3 个答案:

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