我有一个场景,我根据xpath值过滤xml有效负载。
<int:channel id="documentReceiptFilterChannel" />
<int:chain input-channel="documentReceiptFilterChannel" output-channel="nullChannel">
<!-- Filter to discard message if <statusCode> value is 'EMLOK' -->
<int-xml:xpath-filter match-type="regex" match-value="^(?!\bEMLOK\b).*$" discard-channel="nullChannel">
<int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
</int-xml:xpath-filter>
<int:service-activator expression="@opsLogger.logError('TransactionId=' + headers.correlationId, ' Msg=' + @opsExceptionUtils.createOPSExceptionInstance(#root))" />
</int:chain>
以下是有效载荷:
<?xml version="1.0" encoding="UTF-8"?>
<GetDocumentReceiptReply xmlns="http://example.org"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<mergeReceiptDeliveryStatus>
<statusCode>EMLOK</statusCode>
</mergeReceiptDeliveryStatus>
</GetDocumentReceiptReply>
我的要求是当<statusCode>EMLOK</statusCode>
元素可用时,丢弃该消息,因此nullChannel
被称为discard-channel
。
但是还有其他值,继续进行链中的下一步并进行错误记录 - <int:service-activator expression="@opsLogger.logError()
。
只要有效负载中存在<statusCode>
元素,上述设置就可以正常工作。但不适用于以下情况:
<statusCode></statusCode>
<statusCode/>
<statusCode>
缺失为了摆脱命名空间问题,xpath表达式形成为<int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
。 xpath值与正则表达式match-type="regex" match-value="^(?!\bEMLOK\b).*$"
匹配(对于值!='EMLOK
')。
<int-xml:xpath-expression />
评估失败后会发生什么?
我唯一的要求是,如果存在<statusCode>EMLOK</statusCode>
,则丢弃该消息,否则为其他所有消息,在日志文件中记录错误。 (而不是抛出将传播到错误通道的异常)。
答案 0 :(得分:0)
您可以编写AbstractXPathMessageSelector
的自定义子类并委托给BooleanTestXPathMessageSelector
和RegexTestXPathMessageSelector
,或者只使用2个过滤器...
<int:chain input-channel="documentReceiptFilterChannel" output-channel="errors">
<int-xml:xpath-filter discard-channel="errors">
<int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
</int-xml:xpath-filter>
<int-xml:xpath-filter match-type="regex" match-value="^(?!\bEMLOK\b).*$">
<int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
</int-xml:xpath-filter>
</int:chain>
<int:service-activator
expression="@opsLogger.logError('TransactionId=' + headers.correlationId, ' Msg=' + @opsExceptionUtils.createOPSExceptionInstance(#root))" />
请注意,您不需要丢弃nullChannel
- 只是省略丢弃渠道会导致丢弃。通过第二个过滤器的消息将转到链的输出通道。
自定义选择器会更高效,因为只需要转换到节点一次。