5

我有一个肥皂请求进入骡子流。我的任务是从有效负载中获取信息,并根据结果将原始请求推送到不同的 jms 队列。

为了从有效负载中获取所需的信息,我使用了 XSLT 转换器(不是 XPath,因为我需要根据 IDREF 从元素中获取 IDREF 属性,然后从 IDREF 对象中获取元素和子元素)。

基于 XSLT 转换的结果,我使用选择元素来推送原始有效负载。我将原始有效负载存储在会话中(也可以在入站中进行)。XSLT 转换后,应用选择路由器找出合适的队列,然后将原始有效负载推入队列(原始有效负载存储在会话变量中)。我正在使用<expression-component>元素。以下是 mule-flow 的片段:

<flow name="ProcessXML121Order">
    <jms:inbound-endpoint queue="mviq.121.order" exchange-pattern="one-way" />
    <logger message="121 order payload is #[payload]" level="INFO" />
    <message-properties-transformer scope="session">
        <add-message-property key="mviPayload" value="#[payload]"/>
    </message-properties-transformer>
    <xm:xslt-transformer xsl-file="chooseVendor.xslt" />
    <logger message="After xsl file payload is #[payload]" level="INFO" />      
    <choice>
        <when expression="'EMSI'">
            <logger message="Vendor is EMSI" level="INFO" />
            <expression-component>payload=#[header:SESSION:mviPayload]</expression-component>
            <jms:outbound-endpoint queue="mviq.121.order.emsi" />
        </when>
        <when expression="'PRMD'">
            <logger message="Vendor is PRMD" level="INFO" />
            <jms:outbound-endpoint queue="mviq.121.order.prmd" />
        </when>
        <when expression="'RSA'">
            <logger message="Vendor is RSA" level="INFO" />
            <logger message="RSA payload is #[payload]" level="INFO" />
            <jms:outbound-endpoint queue="mviq.121.order.rsa" />
        </when>
        <otherwise>
            <logger message="Vendor is Error" level="INFO" />
            <logger message="Vendor error payload is #[payload]" level="INFO" />
            <jms:outbound-endpoint queue="mviq.error" />
        </otherwise>
    </choice>
</flow>

评估 payload=#[header:SESSION:mviPayload] 时抛出以下异常

[ProcessXML121Order.stage1.02] exception.AbstractExceptionListener (AbstractExceptionListener.java:296) - 
********************************************************************************
Message               : Execution of the expression "payload=#[header:SESSION:mviPayload]" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[]
Code                  : MULE_ERROR-29999
--------------------------------------------------------------------------------
Exception stack is:
1. [Error: illegal use of operator: +]
[Near : {... Unknown ....}]
             ^
[Line: 1, Column: 0] (org.mvel2.CompileException)
  org.mvel2.ast.OperatorNode:46 (null)
2. Execution of the expression "payload=#[header:SESSION:mviPayload]" failed. (org.mule.api.expression.ExpressionRuntimeException)
  org.mule.el.mvel.MVELExpressionLanguage:211 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/ExpressionRuntimeException.html)
3. Execution of the expression "payload=#[header:SESSION:mviPayload]" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[] (org.mule.api.MessagingException)
  org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:35 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
[Error: illegal use of operator: +]
[Near : {... Unknown ....}]
             ^
[Line: 1, Column: 0]
    at org.mvel2.ast.OperatorNode.getReducedValueAccelerated(OperatorNode.java:46)
    at org.mvel2.MVELRuntime.execute(MVELRuntime.java:85)
    at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:105)
    + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

我有两个问题:

  1. 如何覆盖原始有效载荷?(不是说这是最好的方法)
  2. 在这种情况下,更好的方法是什么?是否建议保持原始有效负载完整(在这种情况下)并将 XSLT 输出存储在其他变量中?我怎样才能做到这一点?我可以用来实现这一目标的路径(mule 组件)是什么?我对 Mule 很陌生,并寻求社区建议。

感谢您花时间调查此事。

4

4 回答 4

16

在回答你的问题之前,让我们重写这个被破坏的表达式:

<expression-component>payload=#[header:SESSION:mviPayload]</expression-component>

作为:

<set-payload value="#[sessionVars.mviPayload]" />

以下内容也可以使用,但没有充分的理由会更复杂:

<expression-component>payload=sessionVars.mviPayload</expression-component>

还有这个:

<message-properties-transformer scope="session">
    <add-message-property key="mviPayload" value="#[payload]"/>
</message-properties-transformer>

会更好写:

<set-session-variable variableName="mviPayload" value="#[message.payload]" />

现在回答你的问题:

  1. 采用set-payload
  2. 您所做的是最好的:像 XSL-T 这样的转换器自然适用于当前消息有效负载,因此将原始消息保存在属性中然后转换主有效负载就可以了。只有一件事:更喜欢流变量而不是会话变量。实际上,在您的情况下,我认为您不需要此流程之外的原始有效负载,因此在会话中存储是多余的。

所以我建议你使用:

<set-variable variableName="mviPayload" value="#[message.payload]" />

存储原始有效负载和以下内容以重新建立它:

<set-payload value="#[mviPayload]" />
于 2012-12-21T16:56:10.963 回答
0

使用 Set-Payload 并提供要覆盖的数据。

于 2015-08-25T12:52:40.853 回答
0

你可以用很多方法做到这一点。

  1. 使用 set-payload
  2. 使用表达式,#[payload='']
  3. 使用变压器/组件
于 2016-06-27T12:42:27.347 回答
0

您可以保持有效负载不变,并使用消息丰富器将 xslt 转换的值存储在变量中。使用选项内部的变量来确定要转到哪个队列。下面是一个代码片段

 <enricher doc:name="Message Enricher" target="#[flowVars.transformResultVar]">
               <!--perform transformation logic here-->
 </enricher>

参考:https ://dzone.com/articles/content-enrichment-using-mule-message-enricher-com

于 2018-03-22T06:11:19.667 回答