2012-07-31 92 views
2

我使用Apache Camel 2.9.2和Spring 3.0.6.RELEASE。我正在嘗試使用自定義的DataFormat來編組和解組駱駝消息。我想使用Spring將我的自定義DataFormat配置到我的一個路由中。定製Apache Camel數據格式的春天配置

Apache的駱駝的文件指出,爲了我的自定義數據格式掛鉤到春天我只需要聲明我的自定義DATAFORMAT作爲一個bean和引用它我的春節,路線內,像這樣的路線:

<marshal> 
    <custom ref="myCustomDataFormat"/> 
</marshal> 

http://camel.apache.org/custom-dataformat.html

所以,我有以下設置:

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
         http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd 
         http://www.springframework.org/schema/context 
         http://www.springframework.org/schema/context/spring-context-3.0.xsd 
"> 

<bean id="myCustomDataFormat" class="com.test.CustomDataFormat"/> 
<!-- Camel Context --> 
<camelContext xmlns="http://camel.apache.org/schema/spring"> 
    <route> 
     <from uri="file:C:/test?initialDelay=4000&amp;delay=1000"/> 
     <marshal> 
      <custom ref="myCustomDataFormat"/> 
     </marshal> 
     <to uri="file:C:/test2"/> 
    </route> 
</camelContext> 
</beans> 

但是,當我嘗試啓動駱駝,我得到以下討厭埃羅r:

org.springframework.beans.ConversionNotSupportedException:未能將類型'com.test.CustomDataFormat'的值轉換爲所需類型'org.apache.camel.model.DataFormatDefinition';嵌套異常是java.lang.IllegalStateException:無法將[com.test.CustomDataFormat]類型的值轉換爲所需類型[org.apache.camel.model.DataFormatDefinition]:沒有找到匹配的編輯器或轉換策略

我的數據格式定義如下:

package com.test; 

import java.io.InputStream; 
import java.io.OutputStream; 

import org.apache.camel.Exchange; 
import org.apache.camel.spi.DataFormat; 

public class CustomDataFormat implements DataFormat { 

/* (non-Javadoc) 
* @see org.apache.camel.spi.DataFormat#marshal(org.apache.camel.Exchange, java.lang.Object, java.io.OutputStream) 
*/ 
@Override 
public void marshal(Exchange exchange, Object graph, OutputStream stream) 
     throws Exception { 
    System.out.println("Marshal"); 
    byte[] bytes = exchange.getContext().getTypeConverter().mandatoryConvertTo(byte[].class, graph); 
    stream.write(bytes); 

} 

/* (non-Javadoc) 
* @see org.apache.camel.spi.DataFormat#unmarshal(org.apache.camel.Exchange, java.io.InputStream) 
*/ 
@Override 
public Object unmarshal(Exchange exchange, InputStream stream) 
     throws Exception { 
    System.out.println("Unmarshal"); 
    byte[] bytes = exchange.getContext().getTypeConverter().mandatoryConvertTo(byte[].class, stream); 
    return bytes; 
} 
} 

我知道我的CustomDataFormat實施是正確的,因爲我在Java中創建下面的測試路線和它的工作完美

package com.test; 

import org.apache.camel.spring.SpringRouteBuilder; 

public class TestFormatRoute extends SpringRouteBuilder { 

/* (non-Javadoc) 
* @see org.apache.camel.builder.RouteBuilder#configure() 
*/ 
@Override 
public void configure() throws Exception { 
    from("file:C:/test?initialDelay=4000&delay=1000").unmarshal(new CustomDataFormat()).to("file:C:/test2"); 
} 

} 

我缺少什麼?

感謝

更新

讓駱駝收到此錯誤,我發現我不相信我的自定義數據格式實際上在我創建的路線不工作後完全啓動後。我不確定哪個進程嘗試解析我的自定義數據格式並失敗,但顯然不是解析數據格式以放入我的路由的相同進程。

這解決了數據格式的功能要求,但它並不能解釋我爲什麼會收到此錯誤。

我也確認它不是我的數據格式(CustomDataFormat)的名稱導致該問題。將我的DataFormat重命名爲一個唯一的名稱(MerlinDataFormat)並未解決該錯誤。

我仍然想知道爲什麼我收到此錯誤,因爲我的控制檯和日誌文件中的大塊醜陋紅色錯誤並不完全吸引人。

再次感謝。

回答

2

原來是一個很簡單的解決方案(和一個我承認本來應該很容易看到)。實際上有兩種解決這個問題的方法,其中一種只使用spring,另一種需要額外的java類。

解決方案1 ​​

創建擴展DataFormatDefinition具有相同的屬性自定義DataFormat一個新的類。覆蓋configureDataFormat()方法以設置底層DataFormat的所有屬性。添加構造函數以將底層的DataFormat設置爲CustomDataFormat的實例。現在您應該可以在春季創建DataFormatDefinition的實例,並在編組時或unmarshaling時參考。

解決方案2(快速&髒)

春天,創建一個新的DataFormatDefinition bean並設置它的dataFormat財產爲您DataFormat春天bean的引用。現在,您應該能夠在marshalingunmarshaling時參考您的DataFormatDefinition豆。

0

不太清楚你的例子有什麼問題,這似乎很好。你可以發佈你的代碼的數據格式?你是否正確實現了org.apache.camel.spi.DataFormat?

我剛剛設置了這個例子與駱駝2.9.2,它的作品就像一個魅力。自定義數據格式是駱駝文檔/源代碼中的一種。

<bean id="mySweetDf" class="com.example.MySweetDf"/> 
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> 
<route> 
     <from uri="file:C:/temp/test?initialDelay=4000&amp;delay=1000"/> 
     <marshal> 
      <custom ref="mySweetDf"/> 
     </marshal> 
     <convertBodyTo type="java.lang.String"/> 
     <to uri="file:C:/temp/test2"/> 
    </route> 
</camelContext> 

數據格式的Java文件:

package com.example; 
import java.io.InputStream; 
import java.io.OutputStream; 
import org.apache.camel.Exchange; 
import org.apache.camel.spi.DataFormat; 

public class MySweetDf implements DataFormat { 

    public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception { 
    byte[] bytes = exchange.getContext().getTypeConverter().mandatoryConvertTo(byte[].class, graph); 
    String body = reverseBytes(bytes); 
    stream.write(body.getBytes()); 
} 

    public Object unmarshal(Exchange exchange, InputStream stream) throws Exception { 
    byte[] bytes = exchange.getContext().getTypeConverter().mandatoryConvertTo(byte[].class, stream); 
    String body = reverseBytes(bytes); 
    return body; 
} 

    private String reverseBytes(byte[] data) { 
    StringBuilder sb = new StringBuilder(data.length); 
    for (int i = data.length - 1; i >= 0; i--) { 
     char ch = (char) data[i]; 
     sb.append(ch); 
    } 
    return sb.toString(); 
} 
} 

UPDATE

剛試過你的代碼。似乎也工作。通過mvn archetype 168創建一個新的camel 2.9.2項目:remote - > org.apache.camel.archetypes:camel-archetype-spring(創建一個新的支持Spring DSL的Camel項目)。這隻包括駱駝核心和駱駝春天的依賴,沒有別的。

再換成駱駝context.xml中與XML和在java目錄添加的數據格式的代碼。運行「mvn camel:run」將文件複製並在日誌中打印「元帥」。

[pache.camel.spring.Main.main()] SpringCamelContext    INFO Route: route1 started and consuming from: Endpoint[file://C:/test?delay=1000&initialDelay=4000] 
[pache.camel.spring.Main.main()] SpringCamelContext    INFO Total 1 routes, of which 1 is started. 
[pache.camel.spring.Main.main()] SpringCamelContext    INFO Apache Camel 2.9.2 (CamelContext: camel-1) started in 0.808 seconds 
Marshal 

你確定正確的,而不是有所有依賴安裝該食堂的東西了數據格式的一些.jar文件?

UPDATE2

好吧,我想我有一個想法,它是什麼:

http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/model/dataformat/CustomDataFormat.html 駱駝已經有一個命名爲您的數據格式的類。您應該嘗試將其重命名爲其他內容。 CustomDataFormat擴展了org.apache.camel.model.DataFormatDefinition,它在你的錯誤中被引用。 Java應該處理這個問題,因爲它是兩個不同的命名空間,但是在您的項目設置中可能會導致這種衝突。嘗試重命名數據格式並查看是否可以解決問題。

+0

感謝您的回覆。我編輯了我的問題,包括我的DataFormat和Java Route來證明DataFormat實現是正確的。你可以發佈你的完整文件爲你的駱駝春季配置?我很好奇,看看我們的xml上下文或schemeLocations是不同的。謝謝。 – MerlinOfMines 2012-08-01 14:07:58

+0

我添加了到ActiveMQ 5.6(conf/camel.xml)的路由,它應該是一個標準的spring xml。測試你的代碼,它似乎工作,檢查我更新的答案。 – 2012-08-01 19:35:14

+0

Petter,請參閱我的問題中的更新2。我證實這不是我的DataFormat的名稱是問題。 – MerlinOfMines 2012-08-02 14:20:38

0

我也正面臨與駱駝2.10.0同樣的問題。如果你提供一個類型爲org.apache.camel.model.DataFormatDefinition的實例,那麼一切正常!我可以看到兩個用於xmljson轉換的類 - >實現DataFormat和DataFormatDefinition的XmlJsonDataFormat。

我解決了同樣的問題,我也面臨着。 實現了擴展DataFormatDefintion的類 - 它的configureDataFormat方法爲擴展DataFormat的類設置可注入屬性(在你的情況下這是CustomDataFormat)。 我用XmlJson轉換作爲模板來解決。