定制ApacheCamel数据格式的Spring配置
我正在使用ApacheCamel 2.9.2和Spring3.0.6.0版本。我正在尝试使用自定义数据格式封送和解封送驼峰消息。我想使用Spring将自定义数据格式配置到我的一条路由中 Apache Camel的文档指出,为了在Spring中将自定义数据格式连接到路由,我只需要将自定义数据格式声明为bean,并在Spring路由中引用它,如下所示:定制ApacheCamel数据格式的Spring配置,spring,apache-camel,dataformat,Spring,Apache Camel,Dataformat,我正在使用ApacheCamel 2.9.2和Spring3.0.6.0版本。我正在尝试使用自定义数据格式封送和解封送驼峰消息。我想使用Spring将自定义数据格式配置到我的一条路由中 Apache Camel的文档指出,为了在Spring中将自定义数据格式连接到路由,我只需要将自定义数据格式声明为bean,并在Spring路由中引用它,如下所示: <marshal> <custom ref="myCustomDataFormat"/> </marshal&
<marshal>
<custom ref="myCustomDataFormat"/>
</marshal>
我知道我的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");
}
}
我错过了什么
谢谢
更新
在收到此错误后让Camel完全启动后,我发现自己的自定义数据格式在我创建的路由中确实起作用,这让我难以置信。我不确定是哪个进程试图解析我的自定义数据格式并失败,但显然不是解析要放入路由的数据格式的同一进程
这解决了数据格式的功能需求,但它并没有解释我收到此错误的原因
我还确认,导致问题的不是我的数据格式(CustomDataFormat)的名称。将我的DataFormat重命名为唯一名称(MerlinDataFormat)无法修复错误
我仍然想知道为什么我会收到这个错误,因为我的控制台和日志文件中的大块难看的红色错误并不吸引人
再次感谢。不太确定您的示例有什么问题,它看起来很好。您可以发布数据格式的代码吗?您是否正确地实现了org.apache.camel.spi.DataFormat 我刚刚用Camel 2.9.2建立了这个例子,它就像一个符咒。自定义数据格式是来自Camel文档/源代码的格式
<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&delay=1000"/>
<marshal>
<custom ref="mySweetDf"/>
</marshal>
<convertBodyTo type="java.lang.String"/>
<to uri="file:C:/temp/test2"/>
</route>
</camelContext>
更新
刚刚试过你的代码。看起来也很管用。通过mvn原型168:remote->org.apache.camel.archetypes:camel-archetypespring创建了一个新的camel 2.9.2项目(创建了一个新的camel项目,添加了spring DSL支持)。这只包括camel核心和camel-spring依赖项,没有其他内容
然后用xml替换camel-context.xml,并在java目录中添加数据格式代码。带有“mvn camel:run”的运行复制了文件并在日志中打印了“marshal”
[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文件将数据格式搞得一团糟吗
更新2
好吧,我想我知道它是什么了:
Camel已经有一个名为数据格式的类。您应该尝试将其重命名为其他名称。CustomDataFormat扩展了错误中引用的org.apache.camel.model.DataFormatDefinition。Java应该处理这个问题,因为它是两个不同的名称空间,但您的项目设置中可能存在导致此冲突的问题。尝试重命名数据格式,看看这是否解决了问题。camel 2.10.0也面临同样的问题。如果您为ref提供类型为org.apache.camel.model.DataFormatDefinition的实例,则一切正常!!我可以看到两个xmljson转换类-->XmlJsonDataFormat实现了DataFormat和DataFormatDefinition 我解决了我同样面临的问题。 实现了一个扩展DataFormatDefinition的类-它在configureDataFormat方法中为扩展DataFormat的类设置可注入属性(在您的示例中,这是CustomDataFormat)。
我使用XmlJson转换作为解决问题的模板。结果证明这是一个非常简单的解决方案(我承认这应该很容易看到)。实际上有两种方法可以解决这个问题,一种只使用spring,另一种需要额外的java类 解决方案1 创建一个新的扩展类
DataFormatDefinition
,该类具有与自定义DataFormat
相同的属性。重写configureDataFormat()
方法以设置基础DataFormat
的所有属性。添加构造函数以将基础DataFormat
设置为CustomDataFormat
的实例。现在,您应该能够在spring中创建DataFormatDefinition
的实例,并在封送或解组时引用它
解决方案2(快脏)
在spring中,创建一个新的DataFormatDefinition
bean,并将其dataFormat
属性设置为对dataFormat
springbean的引用。现在,当封送
或解组
时,您应该能够引用数据格式定义
bean 谢谢你的回复。我编辑了我的问题,包括我的DataFormat和Java路由,以证明DataFormat实现是正确的。您可以发布您的Camel-Spring配置的完整文件吗?我很想知道我们的xml上下文或模式位置是否不同。谢谢。我将路由添加到ActiveMQ5.6(conf/camel.xml),它应该是标准的SpringXML。测试你的代码,它似乎工作,检查我的更新答案。佩特,见更新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&delay=1000"/>
<marshal>
<custom ref="mySweetDf"/>
</marshal>
<convertBodyTo type="java.lang.String"/>
<to uri="file:C:/temp/test2"/>
</route>
</camelContext>
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();
}
}
[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