2012-11-10 19 views
0

我的應用程序正在做的是創建一個大的csv文件(它是一個報告),其想法是傳遞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字節。

克服此問題的最佳方法是什麼?

我的技術堆棧是java 6和play framework 1.2.5。

注:響應對象的起源是play.mvc.Controller.response

+0

你缺少'文件名='從第一標題 –

+0

不,不是這樣,添加它後仍然是同樣的錯誤。 – cptdanko

+1

我並不是說這是導致錯誤的問題。剛剛注意到其他的錯誤。 –

回答

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

我們用這個直接在瀏覽器中顯示動作的結果,

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

我不知道關於內存不足的錯誤,但我想至少嘗試這個辦法:

request.format = "csv"; 
renderBinary(new ByteArrayInputStream(csvContents)); 
0

顯然網狀抱怨說,HTTP頭太長 - 也許在某種程度上認爲你文件頭的一部分,也看到

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