如何停止骆驼做 While 循环
How to stop camel doWhile loop
我们有一个独立的包,它基于几个 header 变量 [direct-vm:createPartService] 创建工厂部件。
我的应用程序需要遍历零件列表并重复调用该包。我的 partBean.update 方法只是从零件列表中检索零件信息,设置 header 变量,然后调用 createPartService。
我使用以下 doWhile 循环。我发现当 createPartService return status 为 ERROR 时,以下循环完美运行。工作流退出循环并转到异常处理部分。但是,当 createPartService return 状态永远不会出错时,即每个 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>
骆驼似乎不接受逻辑'and'。上面的评价总是returns false。我还尝试用 'and' 或相应的 html 实体替换“&&”。没有区别。关于遍历列表并在没有错误时优雅退出的任何建议?
您没有正确设置循环终止条件。
Use a bean to control your looping terminate condition
驼色SpringXML
<loop doWhile="true">
<simple resultType="java.lang.Boolean">${bean:partBean?method=isContinueLoop}</simple>
... do stuff here ...
</loop>
Java豆子
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 中的系统打印,您可以观察到 CamelLoopIndex 的值更改为:null -> 0 -> 1 -> 2 -> ...,null 值为使您的条件 return 为假的根本问题。为了在 Camel Spring XML 简单语言中避免这种情况,您需要使用 OR 运算符对 CamelLoopIndex 进行空检查。
从这个意义上讲,您将需要 AND 运算符和 OR 运算符。但是,目前 Simple language page 节 'Using and / or'.
中的简单语言不支持此功能
<split>
为我的用例提供了一个很好的解决方案。在下面的代码示例中,findParts 方法 returns 部分 object 的列表。更新方法设置 header 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>
如果你想在特定回合后停止循环,你可以使用这个:
from("direct:test").setProperty("CamelLoopIndex",constant(0)).loopDoWhile(simple("${exchangeProperty.CamelLoopIndex} <= 3")).log("=====${exchangeProperty.CamelLoopIndex}");
注意你必须在循环之前显式声明CamelLoopIndex 属性,否则Camel在启动路由时将无法理解contiditon,因为CamelLoopIndex 属性是在循环开始后创建的。
我们有一个独立的包,它基于几个 header 变量 [direct-vm:createPartService] 创建工厂部件。
我的应用程序需要遍历零件列表并重复调用该包。我的 partBean.update 方法只是从零件列表中检索零件信息,设置 header 变量,然后调用 createPartService。
我使用以下 doWhile 循环。我发现当 createPartService return status 为 ERROR 时,以下循环完美运行。工作流退出循环并转到异常处理部分。但是,当 createPartService return 状态永远不会出错时,即每个 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>
骆驼似乎不接受逻辑'and'。上面的评价总是returns false。我还尝试用 'and' 或相应的 html 实体替换“&&”。没有区别。关于遍历列表并在没有错误时优雅退出的任何建议?
您没有正确设置循环终止条件。
Use a bean to control your looping terminate condition
驼色SpringXML
<loop doWhile="true">
<simple resultType="java.lang.Boolean">${bean:partBean?method=isContinueLoop}</simple>
... do stuff here ...
</loop>
Java豆子
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 中的系统打印,您可以观察到 CamelLoopIndex 的值更改为:null -> 0 -> 1 -> 2 -> ...,null 值为使您的条件 return 为假的根本问题。为了在 Camel Spring XML 简单语言中避免这种情况,您需要使用 OR 运算符对 CamelLoopIndex 进行空检查。
从这个意义上讲,您将需要 AND 运算符和 OR 运算符。但是,目前 Simple language page 节 'Using and / or'.
中的简单语言不支持此功能<split>
为我的用例提供了一个很好的解决方案。在下面的代码示例中,findParts 方法 returns 部分 object 的列表。更新方法设置 header 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>
如果你想在特定回合后停止循环,你可以使用这个:
from("direct:test").setProperty("CamelLoopIndex",constant(0)).loopDoWhile(simple("${exchangeProperty.CamelLoopIndex} <= 3")).log("=====${exchangeProperty.CamelLoopIndex}");
注意你必须在循环之前显式声明CamelLoopIndex 属性,否则Camel在启动路由时将无法理解contiditon,因为CamelLoopIndex 属性是在循环开始后创建的。