使用 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 路由器使用可選的 欲瞭解更多資訊,請參見 |
例如,如果我們要根據根節點的名稱進行路由,可以使用以下配置
<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() <= 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 型別負載之間進行轉換。如果您需要擴充套件該預設實現的功能,那麼在大多數情況下,上游轉換器通常是更好的選擇,而不是在此處提供對此策略的自定義實現的引用。