2012-09-10 33 views
2

我有我爲我的春天控制器創建調用從使用SuperCSV庫豆的集合生成CSV工具類(http://supercsv.sourceforge.net/SuperCSV的不可讀輸出?

實用類是非常基本的:

public static void export2CSV(HttpServletResponse response, 
     String[] header, String filePrefix, List<? extends Object> dataObjs) { 
    try{ 
     response.setContentType("text/csv;charset=utf-8"); 
     response.setHeader("Content-Disposition","attachment; filename="+filePrefix+"_Data.csv"); 

     OutputStream fout= response.getOutputStream(); 
     OutputStream bos = new BufferedOutputStream(fout); 
     OutputStreamWriter outputwriter = new OutputStreamWriter(bos); 

     ICsvBeanWriter writer = new CsvBeanWriter(outputwriter, CsvPreference.EXCEL_PREFERENCE); 

     // the actual writing 
     writer.writeHeader(header); 

     for(Object anObj : dataObjs){ 
      writer.write(anObj, header);         
     } 
    }catch (Exception e){ 
     e.printStackTrace(); 
    } 
}; 

的趕上,我得到了不同的行爲,我不知道爲什麼。當我從一個控制器(我們稱之爲'A')調用它時,我得到了預期的數據輸出。

當我從另一個控制器('B')調用它時,我得到一個無法識別的二進制數據的一小部分,無法由OO Calc打開。在Notepad ++中打開它會產生一個不可讀的亂碼,我只能假設讀者試圖向我顯示一個二進制流。

控制器 'A' 調用(正常工作的那個)

@RequestMapping(value="/getFullReqData.html", method = RequestMethod.GET) 
public void getFullData(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws IOException{ 
    logger.info("INFO: ******************************Received request for full Req data dump"); 
    String projName= (String)session.getAttribute("currentProject"); 
    int projectID = ProjectService.getProjectID(projName); 
    List<Requirement> allRecords = reqService.getFullDataSet(projectID); 

     final String[] header = new String[] { 
       "ColumnA", 
       "ColumnB",     
       "ColumnC", 
       "ColumnD", 
       "ColumnE" 
       }; 

     CSVExporter.export2CSV(response, header, projName+"_reqs_", allRecords); 


}; 

...這是控制器 'B' 調用(失敗的):

@RequestMapping(value="/getFullTCData.html", method = RequestMethod.GET) 
public void getFullData(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws IOException{ 
    logger.info("INFO: Received request for full TCD data dump"); 
    String projName= (String)session.getAttribute("currentProject"); 
    int projectID = ProjectService.getProjectID(projName); 
    List<TestCase> allRecords = testService.getFullTestCaseList(projectID); 

    final String[] header = new String[] { 
      "ColumnW", 
      "ColumnX", 
      "ColumnY",     
      "ColumnZ" 
     }; 

    CSVExporter.export2CSV(response, header, projName+"_tcs_", allRecords); 
} 

觀察:

  • 我首先調用哪個控制器是不相關的。 「A」永遠可行,「B」總是產生亂碼
  • 這個函數兩種電話已經是在傳遞給CSVWriter
  • 簡單的在bean定義的總的操作集合的子集標題列的列表異常的printStackTrace正在檢測,當一個bean的反射場不定義相匹配(即找不到get()方法來獲得編程的值),這表明所有列/變量的對決都取得了成功。
  • 在調試器中,我已經驗證了writer.write(對象,標題)呼叫被擊中基於對象傳遞的次數預期數量以及這些對象有預期的數據

任何建議或見解將不勝感激。我真的難住如何更好地隔離問題...

+0

你是否關閉了作家? –

回答

2

你沒有關閉作家。另外,CsvBeanWriter會將作者包裝在BufferedWriter中,所以你也可以簡化你的outputwriter

public static void export2CSV(HttpServletResponse response, 
     String[] header, String filePrefix, List<? extends Object> dataObjs) { 
    ICsvBeanWriter writer; 
    try{ 
     response.setContentType("text/csv;charset=utf-8"); 
     response.setHeader("Content-Disposition", 
      "attachment; filename="+filePrefix+"_Data.csv"); 

     OutputStreamWriter outputwriter = 
      new OutputStreamWriter(response.getOutputStream()); 

     writer = new CsvBeanWriter(outputwriter, CsvPreference.EXCEL_PREFERENCE); 

     // the actual writing 
     writer.writeHeader(header); 

     for(Object anObj : dataObjs){ 
      writer.write(anObj, header);         
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      writer.close(); // closes writer and underlying stream 
     } catch (Exception e){} 
    } 
}; 

Super CSV 2.0.0-beta-1已經出來!除了添加許多其他功能(包括Maven支持和新的Dozer擴展)之外,CSV編寫者現在也公開了flush()方法。

+0

明白了。然而,我感到困惑,爲什麼調用方法(不管順序)是從一個控制器調用中起作用的,並且如果問題出現在被調用的方法中,則失敗了。 – Raevik

+0

@Brent也許數據的大小有影響? –