2

SuperCSV ライブラリ ( http://supercsv.sourceforge.net/ )を使用して Bean のコレクションから CSV を生成するために呼び出すために、Spring コントローラー用に作成したユーティリティ クラスがあります。

ユーティリティ クラスは非常に基本的なものです。

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

問題は、この操作からさまざまな動作が得られていることです。その理由はわかりません。これを 1 つのコントローラー (「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(Object, header) 呼び出しが、渡されるオブジェクトの数に基づいて予想される回数ヒットし、これらのオブジェクトに予想されるデータがあることを確認しました。

提案や洞察をいただければ幸いです。問題をより適切に切り分ける方法に本当に困惑しています...

4

1 に答える 1

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()メソッドも公開するようになりました。

于 2012-09-10T21:56:49.230 に答える