使用 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.