使用 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
表达式的结果是两个值(responderA
和 responderB
),但你不想将响应者名称与通道名称耦合,你可以提供额外的映射配置,比如如下内容:
<!-- 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>
XML 负载转换器
对于 XPath 路由器,您还可以指定在转换有效负载以进行 XPath 评估之前使用的转换器。因此,XPath 路由器支持 XmlPayloadConverter
策略的自定义实现,并且在 XML 中配置 xpath-router
元素时,可以通过 converter
属性提供此类实现的引用。
如果未明确提供此引用,则使用 DefaultXmlPayloadConverter
。在大多数情况下,这应该已经足够,因为它可以转换来自 Node、Document、Source、File 和 String 类型的有效负载。如果您需要超出该默认实现的功能,则在大多数情况下,使用上游 Transformer 通常是一个更好的选择,而不是在这里提供对此策略的自定义实现的引用。