2011-06-23 96 views
1

我正試圖用Apache Camel寫我的第一個代碼。我試圖遵循Camel in Action的示例,但我想使用我自己的示例數據。如何使用Apache Camel和Bindy從CSV解組到Bean?

我想做

現在我想從一個CSV文件中讀取並獲得每行一個Java bean什麼。

這裏是我的JUnit測試:

@Test 
public void testCsvWithBindy() throws Exception { 
    MockEndpoint mock = getMockEndpoint("mock:queue.csv"); 
    mock.expectedMessageCount(2); 

    assertMockEndpointsSatisfied(); 

    CsvBean line1 = mock.getReceivedExchanges().get(0).getIn() 
      .getBody(CsvBean.class); 
    assertEquals("row 01", line1.getFirst()); 
} 

public RouteBuilder createRoute() { 
    return new RouteBuilder() { 
     public void configure() throws Exception { 
      context.setTracing(true); 

      from("file://src/test/resources?noop=true&fileName=test.csv") 
       .unmarshal().bindy(BindyType.Csv, "my.package.for.csvrecord") 
       .to("mock:queue.csv"); 
     } 
    }; 
} 

的CSV包含此:

row 01,row 02,,row 04 
row 11, row 12, row 13, row 14 

這是我CsvRecord:

@CsvRecord(separator = ",") 
public class CsvBean { 
@DataField(pos = 1) 
private String first; 
@DataField(pos = 2) 
private String second; 
@DataField(pos = 3) 
private String third; 
@DataField(pos = 4) 
private String fourth; 

public String getFirst() { 
    return first; 
} 

public void setFirst(String first) { 
    this.first = first; 
} 

public String getSecond() { 
    return second; 
} 

public void setSecond(String second) { 
    this.second = second; 
} 

public String getThird() { 
    return third; 
} 

public void setThird(String third) { 
    this.third = third; 
} 

public String getFourth() { 
    return fourth; 
} 

public void setFourth(String fourth) { 
    this.fourth = fourth; 
} 
} 

我的問題

當我運行這個測試,噸他的上下文被啓動並且路由被加載。但沒有任何事情可以通過。大約10秒後,上下文自動停止,測試失敗。這是堆棧跟蹤:

java.lang.AssertionError: mock://queue.csv Received message count. Expected: <2> but was: <0> 
at org.apache.camel.component.mock.MockEndpoint.fail(MockEndpoint.java:1086) 
at org.apache.camel.component.mock.MockEndpoint.assertEquals(MockEndpoint.java:1068) 
at org.apache.camel.component.mock.MockEndpoint.doAssertIsSatisfied(MockEndpoint.java:367) 
at org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied(MockEndpoint.java:346) 
at org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied(MockEndpoint.java:334) 
at org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied(MockEndpoint.java:172) 
at org.apache.camel.test.junit4.CamelTestSupport.assertMockEndpointsSatisfied(CamelTestSupport.java:391) 
at my.package.for.unittests.CsvToBeanWithBindyTest.testCsvWithBindy(CsvToBeanWithBindyTest.java:20) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 

需要與

幫我想我缺少明顯的東西,或許真的有做的測試設置和沒有那麼多與我CsvRecord或我的路線。你能給我一個提示或者一個更好的教程網址嗎?這本書是不是在這一點上是非常有幫助的...... :-(

回答

2

再次,發佈我的問題之後,我發現自己的答案;-)這裏是一個工作JUnit測試:

public class CsvToBeanWithBindyTest extends CamelTestSupport { 
@Test 
public void testCsv() throws Exception { 
    MockEndpoint mock = getMockEndpoint("mock:queue.csv"); 
    mock.expectedMessageCount(1); 

    assertMockEndpointsSatisfied(); 

    List line1 = (List) mock.getReceivedExchanges().get(0).getIn() 
      .getBody(); 
    Map map1 = (Map) line1.get(0); 
    CsvBean csv1 = (CsvBean) map1.get("my.package.CsvBean"); 
    assertEquals("row 01", csv1.getFirst()); 

    Map map2 = (Map) line1.get(1); 
    CsvBean csv2 = (CsvBean) map2.get("my.package.CsvBean"); 
    assertEquals("row 11", csv2.getFirst()); 
} 

@Override 
protected RouteBuilder createRouteBuilder() throws Exception { 
    return new RouteBuilder() { 
     @Override 
     public void configure() throws Exception { 
      context.setTracing(true); 

      from("file://src/test/resources?noop=true&fileName=test.csv") 
       .unmarshal(new BindyCsvDataFormat("my.package")) 
       .to("mock:queue.csv"); 
     } 
    }; 
} 
} 

對我來說意想不到的是,我從我的終端路由中獲得List,這反過來又保存了許多Map。每個地圖都有一個關鍵字my.package.MyBeanClass,其值設置爲來自我的CSV文件的實際未編組行。

+0

你有沒有解決地圖問題?我也是地圖,我必須從中提取出bean,而不是bean的ArrayList?這個頁面(http://camel.apache.org/bindy.html)引用了這張地圖,但沒有給出足夠的解釋它爲什麼在那裏? – Clarkey

+0

對不起,我沒有在地圖上更新。我接受它作爲Bindy的工作方式: 「這背後的原因是每條線可以對應多個對象,當您只希望每行返回一個對象時,這可能會令人困惑。 (從URL) – cringe

+0

嗨,我也做同樣的CSV到對象轉換,但我面臨int或Integer數據類型的非法參數異常。請檢查我的問題相同 - http://stackoverflow.com/questions/20627864/apache-camelbindy-illegal-argument-exception – vashishth