我的 Mule Flow 中需要一个 while 循环来从自定义 DAO(我使用 Expression Transformer 访问 DAO)中以 block 的形式加载数据,直到他不再提供任何项目为止。 (我不知道 DAO 提供的项目总数。)Mule 3.4 中没有内置 while 循环。
我的第一个想法是在 SubFlow 中使用递归反向引用。 SubFlow 会调用自身直到工作完成。但是我得到了一个“无法解决的循环引用”的 springframework 异常。 Flow 不能调用自己。
我的下一个想法是编写自定义转换器并注入(inject) SubFlow 以在循环中调用。我使用了 David Dossot 在他对这个问题的回答中描述的一些技术:https://stackoverflow.com/a/16532977/2629741
我遇到的问题不仅是原始流程中的 flowVars 在 SubFlow 中不可访问,而且如果我尝试设置 flowVar(并且我使用 flowVars 进行原始流程和子流):
org.mule.api.transformer.TransformerMessagingException: null (java.lang.NullPointerException). Message payload is of type: NullPayload
我的问题是:如何使我在自定义转换器内部调用的子流中可访问原始流中的流变量(反之亦然)(请参阅下面的循环类)?
Mule 流:
<flow name="test_loopFlow1" doc:name="test_loopFlow1">
<vm:inbound-endpoint exchange-pattern="request-response" path="test_loop" doc:name="VM"/>
<custom-transformer class="com.example.transformer.Loop" doc:name="Java">
<spring:property name="flow" ref="loopTask"/>
</custom-transformer>
</flow>
<sub-flow name="loopTask" doc:name="loopTask">
<logger message="loop" level="WARN" doc:name="Logger"/>
<set-variable variableName="stop" value="true" doc:name="set flowVar"/>
</sub-flow>
环路变压器:
public class Loop
extends AbstractMessageTransformer
implements FlowConstructAware
{
private InterceptingChainLifecycleWrapper _flow = null;
public void setFlow(
final Object value
) {
this._flow = InterceptingChainLifecycleWrapper.class.cast(value);
}
@Override
public Object transformMessage(
final MuleMessage message,
final String outputEncoding
) throws TransformerException
{
try {
final MuleEvent muleEvent = new DefaultMuleEvent(
message,
MessageExchangePattern.REQUEST_RESPONSE,
this.flowConstruct
);
message.setInvocationProperty("stop", "false");
do {
/*final MuleEvent resultEvent =*/ this._flow.process(muleEvent);
} while(
((String) message.getInvocationProperty("stop")).equals("false")
);
} catch (final MuleException e) {
throw new TransformerException(
MessageFactory.createStaticMessage("SubFlow exception."),
this
);
}
return message;
}
FlowConstruct flowConstruct;
@Override
public void setFlowConstruct(final FlowConstruct flowConstruct)
{
this.flowConstruct = flowConstruct;
}
}
单元测试:
public class LoopTest
extends FunctionalTestCase
{
private LocalMuleClient _muleClient = null;
public LoopTest(
) throws Exception
{
super.setUpMuleContext();
this._muleClient = new DefaultLocalMuleClient(
AbstractMuleContextTestCase.muleContext
);
}
@Override
protected String getConfigResources(
) {
return "src/main/app/test_loop.xml";
}
@Test
public void testVm(
) throws Exception
{
this._muleClient.send("vm://test_loop", null, null);
}
}
最佳答案
一种不需要任何 Java 代码的简单方法是:
<flow name="stackoverflowFlow1" doc:name="stackoverflowFlow1">
<vm:inbound-endpoint exchange-pattern="one-way" path="in" doc:name="VM"/>
<set-variable variableName="#['counter']" value="#[0]" doc:name="Variable"/>
<flow-ref name="stackoverflowFlow2" doc:name="Flow Reference"/>
</flow>
<flow name="stackoverflowFlow2" doc:name="stackoverflowFlow2">
<logger level="INFO" doc:name="Logger"/>
<set-variable variableName="counter" value="#[flowVars['counter']+1]" doc:name="Variable"/>
<choice doc:name="Choice">
<when expression="#[flowVars['counter']==10]">
<logger level="INFO" doc:name="Logger"/>
</when>
<otherwise>
<flow-ref name="stackoverflowFlow2" doc:name="Flow Reference"/>
</otherwise>
</choice>
</flow>
在这种情况下,我将在 10 次迭代后停止 while
关于java - 在 Mule 3.4 中模拟 while 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19661454/