我的路线中有一个重复的模式 - 每次调用时,某个处理器需要相同的3个Header设置,所以我的路由中有以下代码大约10次以上:
.whatever()
.setHeader("foo1", "bar1")
.setHeader("foo2", "bar2")
.setHeader("foo3", "bar3")
.processRef("processorBazThatNeedsHeaders")
.whatever()
每次都会以不同的方式填充标题,因此将其抽象为子路径并不能真正为我买任何东西。
我喜欢能够做的是将RouteDefinition子类化为在我的DSL中使用另一种方法来允许我这样做:
.whatever()
.bazProcessor("bar1", "bar2", "bar3")
.whatever()
并在'bazProcessor'中设置标题并调用处理器。
我试图做到这一点,但似乎只有一些严重的可能不会用于未来的手术,而且似乎others have had similar luck。
我需要将它们设置为标题,而不是将它们作为参数直接传递给处理器,因为这些值也会在处理器之后用于路由。
是否有一些隐藏的设施来实现这样的目标?
答案 0 :(得分:6)
通过继承RouteDefinition
您的扩展程序只能在from(...)
之后直接显示。如果您想在filter(...)
DSL之后使用DSL扩展,那么这可能是一种限制。
更简单的方法是将逻辑封装在某处,并在实现org.apache.camel.Processor
接口的类中使用它,然后调用.process(...)
或bean(...)
的重载。路由使用逻辑。如果对Processor
实例使用有意义的名称,或者返回Processor
实例的方法,您实际上将非常接近DSL扩展。这是一个example of the suggested approach。最后,您的代码可能如下所示:
.whatever()
.process( setTheHeadersForBaz )
.whatever()
仅供参考:如果您确实需要进行DSL,则有一个项目可以扩展Camel DSL based on Groovy。我想基于Camel Scala DSL的Scala方式也可以选择。
答案 1 :(得分:1)
因此,您只需设置标头,因为您希望处理器能够访问这些值吗?
如果是这样,那么使用Factory的简单示例可能如下所示:
whatever()
.process(BazProcessorFactory.instance("bar1", "bar2", "bar3"))
.whatever()
BazProcessorFactory只是处理器的包装器:
public class BazProcessorFactory {
public Processor instance(final String...vals) {
return new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
//access your array of values here
System.out.println("Foo1 = "+vals[0]);
}
}
}
}
答案 2 :(得分:1)
虽然稍微不相关,但以下是扩展Scala DSL的示例。
我们可以通过隐式类为DSL特征创建隐式方法。
object DSLImplicits {
implicit class RichDSL(val dsl: DSL) {
def get = dsl.setHeader(Exchange.HTTP_METHOD, _ => HttpMethods.GET.name)
def post = dsl.setHeader(Exchange.HTTP_METHOD, _ => HttpMethods.POST.name)
}
}
并像这样使用它。
import DSLImplicits.RichDSL
//----------------------------
from("someWhere")
//Do some processing
.get.to("http://somewhere.com")
更多细节@ http://siliconsenthil.in/blog/2013/07/11/apache-camel-with-scala-extending-dsl/