我们有一个独立的捆绑包,根据一些头变量[direct-vm:createPartService]创建工厂部件。
我的应用程序需要循环遍历部件列表并重复调用此捆绑包。我的partBean.update方法只是从零件列表中检索零件信息,设置头变量然后调用createPartService。
我使用以下doWhile循环。我发现当createPartService返回状态为ERROR时,以下循环完美地工作。工作流从循环退出并转到异常处理部分。但是,当createPartService返回状态永远不会出错时,即每个createPartService都是SUCCESS时,while循环永远不会停止。
<loop doWhile="true">
<simple>${header.STATUS} == 'SUCCESS'</simple>
<bean ref="partBean" method="update"/>
<to uri="direct-vm:createPartService"/>
<choice>
<when>
<simple>${header.STATUS} == 'ERROR'</simple>
<throwException exceptionType="java.lang.Exception message="${header.ERROR_MESSAGE}"/>
<to uri="mock:endPartsError"/>
</when>
<otherwise>
<log message="### update part succeeded" loggingLevel="DEBUG"/>
</otherwise>
</choice>
</loop>
然后,我尝试了另一种情况,
<simple>${header.STATUS} == 'SUCCESS' && ${exchangeProperty[CamelLoopIndex]} < ${headers.PART_COUNT}</simple>
Camel似乎不接受逻辑&#39;和&#39;。上述评估总是返回false。我也尝试过替换&amp;&amp;&amp;&#39;与&#39;和&#39;,或相应的html实体。没有区别。有没有关于循环遍历列表并在没有错误时优雅退出的建议?
答案 0 :(得分:0)
您没有正确设置循环终止条件。
使用bean来控制循环终止条件
Camel Spring XML
<loop doWhile="true">
<simple resultType="java.lang.Boolean">${bean:partBean?method=isContinueLoop}</simple>
... do stuff here ...
</loop>
Java Bean
public Boolean isContinueLoop(Exchange exchange) throws Exception {
// System.out.println("LoopIndex: " + exchange.getProperty(Exchange.LOOP_INDEX));
Boolean result = false;
String status = exchange.getIn().getHeader("STATUS", String.class);
Integer loopIndex = exchange.getProperty(Exchange.LOOP_INDEX, -1, Integer.class);
int maxSize = exchange.getIn().getHeader("PART_COUNT", Integer.class);
if (status != null && status.equals("SUCCESS") && loopIndex < maxSize) {
result = Boolean.TRUE;
}
return result;
}
条件${header.STATUS} == 'SUCCESS' && ${exchangeProperty[CamelLoopIndex]} < ${headers.PART_COUNT}
的主要问题不在于AND运算符,而是${exchangeProperty[CamelLoopIndex]}
的值。
如果取消注释java bean中的系统print,您可以观察到CamelLoopIndex的值更改为:null - &gt; 0 - &gt; 1 - &gt; 2 - &gt; ...,null值是使条件返回false的根问题。要在Camel Spring XML Simple语言中避免这种情况,您需要使用OR运算符对CamelLoopIndex进行空检查。
从这个意义上说,你需要一个AND运算符和一个OR运算符。但是,目前Simple language page部分&#39;使用和/或&#39;中的状态不支持此功能。
答案 1 :(得分:0)
<split>
为我的用例提供了一个很好的解决方案。在下面的代码示例中,findParts方法返回Part对象的列表。更新方法将设置Web服务调用(createPartService)所需的标头变量。
<route id="WebServiceUpdateParts">
<from uri="direct:updateParts"/>
<split stopOnException="true">
<method ref="partBean" method="findParts"/>
<bean ref="partBean" method="update"/>
<to uri="direct-vm:createPartService"/>
</split>
<to uri="mock:endUpdateParts"/>
</route>