使用 XPath 路由 XML 消息

与基于 SpEL 的路由器类似,Spring Integration 支持基于 XPath 表达式路由消息,这允许您创建具有输入通道但没有输出通道的消息端点。相反,一个或多个输出通道是动态确定的。以下示例展示了如何创建此类路由器

<int-xml:xpath-router id="orderTypeRouter" input-channel="orderChannel">
    <int-xml:xpath-expression expression="/order/type"/>
</int-xml:xpath-router>
有关路由器之间共同属性的概述,请参见通用路由器参数

在内部,XPath 表达式被评估为 NODESET 类型并转换为表示通道名称的 List<String>。通常,此类列表包含单个通道名称。但是,根据 XPath 表达式的结果,如果 XPath 表达式返回多个值,XPath 路由器也可以具有接收方列表路由器的特性。在这种情况下,List<String> 包含多个通道名称。因此,消息被发送到列表中的所有通道。

因此,假设传递给以下路由器配置的 XML 文件包含许多表示通道名称的 responder 子元素,则消息将发送到所有这些通道

<!-- route the order to all responders-->
<int-xml:xpath-router id="responderRouter" input-channel="orderChannel">
    <int-xml:xpath-expression expression="/request/responders"/>
</int-xml:xpath-router>

如果返回值不直接表示通道名称,您可以指定附加的映射参数将这些返回值映射到实际的通道名称。例如,如果 /request/responders 表达式产生两个值(responderAresponderB),但您不想将响应器名称与通道名称耦合,您可以提供附加的映射配置,如下所示

<!-- route the order to all responders-->
<int-xml:xpath-router id="responderRouter" input-channel="orderChannel">
    <int-xml:xpath-expression expression="/request/responders"/>
    <int-xml:mapping value="responderA" channel="channelA"/>
    <int-xml:mapping value="responderB" channel="channelB"/>
</int-xml:xpath-router>

如前所述,XPath 表达式的默认评估类型是 NODESET,它被转换为通道名称的 List<String>,这处理了单个通道场景和多个通道场景。

尽管如此,某些 XPath 表达式可能从一开始就评估为 String 类型。例如,考虑以下 XPath 表达式

name(./node())

此表达式返回根节点的名称。如果使用默认评估类型 NODESET,则会导致异常。

对于这些场景,您可以使用 evaluate-as-string 属性,它允许您管理评估类型。它默认为 FALSE。但是,如果您将其设置为 TRUE,则使用 String 评估类型。

XPath 1.0 指定了 4 种数据类型

  • 节点集

  • 字符串

  • 数字

  • 布尔值

当 XPath 路由器使用可选的 evaluate-as-string 属性评估表达式时,返回值由 XPath 规范中定义的 string() 函数确定。这意味着如果表达式选择多个节点,它将返回第一个节点的字符串值。

欲了解更多信息,请参见

例如,如果我们要根据根节点的名称进行路由,可以使用以下配置

<int-xml:xpath-router id="xpathRouterAsString"
        input-channel="xpathStringChannel"
        evaluate-as-string="true">
    <int-xml:xpath-expression expression="name(./node())"/>
</int-xml:xpath-router>

开箱即用的 #xpath() SpEL 函数 也足够强大,可以与通用路由器定义一起使用,包括接收方列表路由器

<int:recipient-list-router input-channel="xpathRecipientsInput">
    <int:recipient channel="channelA" selector-expression="#xpath(payload, '/passenger/age/text() &lt;= 2', 'boolean')"/>
    <int:recipient channel="channelB" selector-expression="#xpath(payload, '/passenger/age/text() > 12', 'boolean')"/>
</int:recipient-list-router>

XML 负载转换器

对于 XPath 路由器,您还可以指定在 XPath 评估之前用于转换负载的转换器。因此,XPath 路由器支持 XmlPayloadConverter 策略的自定义实现,并且在 XML 中配置 xpath-router 元素时,可以通过 converter 属性提供对此类实现的引用。

如果未明确提供此引用,则使用 DefaultXmlPayloadConverter。在大多数情况下,它应该足够了,因为它可以在 Node、Document、Source、File 和 String 类型负载之间进行转换。如果您需要扩展该默认实现的功能,那么在大多数情况下,上游转换器通常是更好的选择,而不是在此处提供对此策略的自定义实现的引用。

© . This site is unofficial and not affiliated with VMware.