0

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

4

3 回答 3

1

请用

Servlet 输出流

喜欢

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);
于 2012-11-10T03:40:04.060 回答
1

我们使用它直接在浏览器中显示操作的结果,

window.location='data:text/csv;charset=utf8,' + encodeURIComponent(your-csv-data);

我不确定内存不足错误,但我至少会试试这个:

request.format = "csv";
renderBinary(new ByteArrayInputStream(csvContents));
于 2012-11-10T09:01:12.027 回答
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();
    }
}
于 2012-11-10T12:31:40.820 回答