2016-02-17 149 views
0

我寫了一個簡單的測試應用程序,它從數據庫讀取記錄並將結果放入一個csv文件。到目前爲止它工作正常,但列名稱,即標題不放在csv文件中。根據文件,它應該放在那裏。我也嘗試過沒有/流式傳輸和分割,但情況是一樣的。Apache Camel CSV與標題

在管線182頭駱駝單元測試都放在那裏明確:https://github.com/apache/camel/blob/master/components/camel-csv/src/test/java/org/apache/camel/dataformat/csv/CsvDataFormatTest.java

怎麼會這樣很簡單的問題,而不需要遍歷頭解決?我也嘗試過不同的設置,但都一樣。例如分隔符被認爲是我設置的,但是標題不是。也感謝提前回復。

我用駱駝2.16.1這樣的:

final CsvDataFormat csvDataFormat = new CsvDataFormat(); 
csvDataFormat.setHeaderDisabled(false); 
[...] 
from("direct:TEST").routeId("TEST") 
     .setBody(constant("SELECT * FROM MYTABLE")) 
     .to("jdbc:myDataSource?readSize=100") // max 100 records 
//  .split(simple("${body}"))    // split the list 
//  .streaming()       // not to keep all messages in memory 
     .marshal(csvDataFormat) 
     .to("file:extract?fileName=TEST.csv"); 
[...] 

編輯1

我也試圖從exchange.in添加標題。它們在HashSet中有名稱「CamelJdbcColumnNames」。我把它加入到這樣的csvDataFormat:

final CsvDataFormat csvDataFormat = new CsvDataFormat(); 
    csvDataFormat.setHeaderDisabled(false); 
    [...] 
    from("direct:TEST").routeId("TEST") 
      .setBody(constant("SELECT * FROM MYTABLE")) 
      .to("jdbc:myDataSource?readSize=100") // max 100 records 
      .process(new Processor() { 
       public void process(Exchange exchange) throws Exception { 
        headerNames =      (HashSet)exchange.getIn().getHeader("CamelJdbcColumnNames"); 
        System.out.println("#### Process headernames = " + new ArrayList<String>(headerNames).toString()); 
        csvDataFormat.setHeader(new ArrayList<String>(headerNames)); 
         } 
       }) 
       .marshal(csvDataFormat)//.tracing() 
       .to("file:extract?fileName=TEST.csv"); 

中的println()打印的列名,但所產生的CVS文件沒有。

EDIT2 我加入了頭名以身體爲在註釋1中提出這樣的:

.process(new Processor() { 
    public void process(Exchange exchange) throws Exception { 

     Set<String> headerNames = (HashSet)exchange.getIn().getHeader("CamelJdbcColumnNames"); 
     Map<String, String> nameMap = new LinkedHashMap<String, String>(); 
     for (String name: headerNames){ 
      nameMap.put(name, name); 
     } 
     List<Map> listWithHeaders = new ArrayList<Map>(); 
     listWithHeaders.add(nameMap); 

     List<Map> records = exchange.getIn().getBody(List.class); 
     listWithHeaders.addAll(records); 
     exchange.getIn().setBody(listWithHeaders, List.class); 


     System.out.println("#### Process headernames = " + new ArrayList<String>(headerNames).toString()); 
     csvDataFormat.setHeader(new ArrayList<String>(headerNames)); 
    } 
}) 

該提案解決了這個問題,並感謝你們的,但它意味着CsvDataFormat是不是真的有用。 JDBC查詢後的交換主體包含來自HashMaps的ArrayList,其中包含表的一個記錄。 HashMap的關鍵是列的名稱,值是值。所以在CsvDataFormat中設置頭文件輸出的配置值應該足夠用於生成頭文件。你知道一個更簡單的解決方案,還是錯過配置中的某些東西?

回答

1

您使用JDBC從數據庫中獲取數據,因此您需要首先自己將頭添加到消息正文中,以便將其作爲第一行。 jdbc的結果集只是數據,不包括頭文件。

+0

由於做到了。我明確地將這些標題添加到了CsvDataFormat對象,但它們像以前一樣被忽略。見編輯1.你的意思是轉換身體並在那裏插入標題?你能提供一個代碼片段嗎? – Tamas

+0

我會將其設置爲通過您的建議解決,但請回答我的最後一個問題,如果您知道任何其他答案,謝謝。 – Tamas

1

我已經通過重寫BindyCsvDataFormat和BindyCsvFactory

public class BindySplittedCsvDataFormat extends BindyCsvDataFormat { 

    private boolean marshallingfirslLot = false; 

    public BindySplittedCsvDataFormat() { 
     super(); 
    } 

    public BindySplittedCsvDataFormat(Class<?> type) { 
     super(type); 
    } 

    @Override 
    public void marshal(Exchange exchange, Object body, OutputStream outputStream) throws Exception { 
     marshallingfirslLot = new Integer(0).equals(exchange.getProperty("CamelSplitIndex")); 
     super.marshal(exchange, body, outputStream); 
    } 

    @Override 
    protected BindyAbstractFactory createModelFactory(FormatFactory formatFactory) throws Exception { 
     BindySplittedCsvFactory bindyCsvFactory = new BindySplittedCsvFactory(getClassType(), this); 
     bindyCsvFactory.setFormatFactory(formatFactory); 
     return bindyCsvFactory; 
    } 

    protected boolean isMarshallingFirslLot() { 
     return marshallingfirslLot; 
    } 
} 


public class BindySplittedCsvFactory extends BindyCsvFactory { 

    private BindySplittedCsvDataFormat bindySplittedCsvDataFormat; 

    public BindySplittedCsvFactory(Class<?> type, BindySplittedCsvDataFormat bindySplittedCsvDataFormat) throws Exception { 
     super(type); 
     this.bindySplittedCsvDataFormat = bindySplittedCsvDataFormat; 
    } 

    @Override 
    public boolean getGenerateHeaderColumnNames() { 
     return super.getGenerateHeaderColumnNames() && bindySplittedCsvDataFormat.isMarshallingFirslLot(); 
    } 

}