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 バイトを超えています。

この問題を克服する最善の方法は何ですか?

私の技術スタックは、Play フレームワーク 1.2.5 の Java 6 です。

注: 応答オブジェクトのオリジンは play.mvc.Controller.response です

4

3 に答える 3

1

使ってください

サーブレット出力ストリーム

お気に入り

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 に答える