我在两个独立的项目中有两条路线:
setHeader("dataFormatBeanName", constant("myFirstList"))
第一条路线:
public class MyTest {
@Configuration
public static class MyTestConfig extends CamelConfiguration {
@Bean(name = "myFirstList")
public DataFormat getMyFirstListDataFormat() {
return new MyFirstListDataFormat();
}
@Bean(name = "mySecondList")
public DataFormat getMySecondListDataFormat() {
return new MySecondListDataFormat();
}
@Bean
public RouteBuilder route() {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:testFirstDataFormat").setHeader("dataFormatBeanName", constant("myFirstList")).to("direct:myRoute");
from("direct:testSecondDataFormat").setHeader("dataFormatBeanName", constant("mySecondList")).to("direct:myRoute");
}
};
}
}
}
custom(header("dataFormatBeanName"))
(不编译)
任何人都知道我应该从标题中获取我的bean名称以在自定义方法中使用它吗?
@Component
public class MyRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
final RouteDefinition routedefinition = this.from("direct:myRoute");
routedefinition.marshal().custom(??????????).to("netty4:tcp://{{route.address}}:{{port}}?textline=true&sync=true");
}
答案 0 :(得分:0)
经过几个小时的搜索,这里找到了解决方案:
第一堂课没有变化。
第二个类使用匿名DataFormat,在其中我从头部检索bean名称,并在调用其marshal方法之前从camel上下文获取spring bean。 AbstractXxxDataFormat类属于project2,由Project1 DataFormat继承。
@Override
public void configure() throws Exception {
final RouteDefinition routedefinition = this.from("direct:myRoute");
routedefinition.marshal(new DataFormat() {
@Override
public void marshal(final Exchange exchange, final Object graph, final OutputStream stream) throws Exception {
AbstractXxxDataFormat myDataFormat = (AbstractGoalDataFormat) getContext().getRegistry().lookupByName(exchange.getIn().getHeader("dataFormatBeanName", String.class));
myDataFormat.marshal(exchange, graph, stream);
}
@Override
public Object unmarshal(final Exchange exchange, final InputStream stream) throws Exception {
return null;
}
});
routedefinition.to("netty4:tcp://{{route.address}}:{{port}}?textline=true&sync=true");
}
如果有更好的解决方案,我会对此感兴趣。
答案 1 :(得分:0)
您是否尝试simple("${header.dataFormatBeanName}")
访问标题?
此外,为什么不将每个.marshal()调用分解为两个子路由(一个用于formatBeanA,一个用于formatBeanB),然后调用适当的子路由而不是在头部中首先传递格式bean名称。首先设置标题?我相信这可能是一种更清洁的方法。
答案 2 :(得分:0)
如果你真的需要在路由中将它作为变量(而不是在构建器api中使用的谓词),你可以使用内联处理器来提取它:
public class MyRouteBuilder extends RouteBuilder {
public void configure() throws Exception {
from("someEndpoint")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
String beanName = exchange.getHeader("beanNameHeader");
}
});
}
}
但是,在存储提取的beanName时,请注意范围和并发性。
答案 3 :(得分:0)
我的同事(感谢他)找到了明确的解决方案:
在交换属性中设置bean名称: exchange.setProperty(“myDataFormat”,“myDataFormatAutowiredBean”);
使用RecipientList模式和(un)marshal检索dataFormat bean:
routedefinition.recipientList(简单( “DATAFORMAT:$ {property.myDataFormat}:编组”)); routedefinition.recipientList(简单( “DATAFORMAT:$ {property.myDataFormat}:解组”));
非常简洁,工作得很好。