轉換 XML 酬載
本節涵蓋如何轉換 XML 酬載
將轉換器設定為 Bean
本節將說明以下轉換器的工作原理以及如何將它們設定為 Bean
所有 XML 轉換器都擴充 AbstractTransformer
或 AbstractPayloadTransformer
,因此實作 Transformer
。在 Spring Integration 中將 XML 轉換器設定為 Bean 時,您通常會將 Transformer
與 MessageTransformingHandler
結合設定。這讓轉換器可以用作端點。最後,我們討論命名空間支援,它允許將轉換器設定為 XML 中的元素。
UnmarshallingTransformer
UnmarshallingTransformer
讓 XML Source
可以使用 Spring OXM Unmarshaller
的實作進行解組。Spring 的物件/XML 對應支援提供了多種實作,支援使用 JAXB、Castor、JiBX 等進行組譯和解組。解組器需要 Source
的實例。如果訊息酬載不是 Source
的實例,仍然會嘗試轉換。目前,支援 String
、File
、byte[]
和 org.w3c.dom.Document
酬載。若要建立自訂轉換為 Source
,您可以注入 SourceFactory
的實作。
如果您未明確設定 SourceFactory ,則 UnmarshallingTransformer 上的屬性預設會設定為 DomSourceFactory 。 |
從 5.0 版開始,UnmarshallingTransformer
也支援 org.springframework.ws.mime.MimeMessage
作為傳入酬載。當我們透過 SOAP 接收具有 MTOM 附件的原始 WebServiceMessage
時,這會很有用。如需詳細資訊,請參閱 MTOM 支援。
以下範例示範如何定義解組轉換器
<bean id="unmarshallingTransformer" class="o.s.i.xml.transformer.UnmarshallingTransformer">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="org.example" />
</bean>
</constructor-arg>
</bean>
使用 MarshallingTransformer
MarshallingTransformer
讓物件圖可以使用 Spring OXM Marshaller
轉換為 XML。預設情況下,MarshallingTransformer
會傳回 DomResult
。但是,您可以透過設定替代的 ResultFactory
(例如 StringResultFactory
)來控制結果類型。在許多情況下,將酬載轉換為替代的 XML 格式會更方便。若要執行此操作,請設定 ResultTransformer
。Spring Integration 提供了兩個實作,一個轉換為 String
,另一個轉換為 Document
。以下範例設定一個組譯轉換器,將轉換為文件
<bean id="marshallingTransformer" class="o.s.i.xml.transformer.MarshallingTransformer">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="org.example"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>
</constructor-arg>
</bean>
預設情況下,MarshallingTransformer
會將酬載物件傳遞至 Marshaller
。但是,如果其布林值 extractPayload
屬性設定為 false
,則整個 Message
實例會改為傳遞至 Marshaller
。這對於 Marshaller
介面的某些自訂實作可能很有用,但通常,當您委派給任何各種 Marshaller
實作時,酬載是組譯的適當來源物件。
XsltPayloadTransformer
XsltPayloadTransformer
使用 可延伸樣式表語言轉換 (XSLT) 轉換 XML 酬載。轉換器的建構函式需要傳入 Resource 或 Templates 的實例。傳入 Templates
實例可以更廣泛地設定用於建立範本實例的 TransformerFactory
。
與 UnmarshallingTransformer
一樣,XsltPayloadTransformer
會針對 Source
實例執行實際的 XSLT 轉換。因此,如果訊息酬載不是 Source
的實例,仍然會嘗試轉換。直接支援 String
和 Document
酬載。
若要建立自訂轉換為 Source
,您可以注入 SourceFactory
的實作。
如果未明確設定 SourceFactory ,則 XsltPayloadTransformer 上的屬性預設會設定為 DomSourceFactory 。 |
預設情況下,XsltPayloadTransformer
會建立具有 Result
酬載的訊息,類似於 XmlPayloadMarshallingTransformer
。您可以透過提供 ResultFactory
或 ResultTransformer
來自訂此設定。
以下範例設定一個作為 XSLT 酬載轉換器運作的 Bean
<bean id="xsltPayloadTransformer" class="o.s.i.xml.transformer.XsltPayloadTransformer">
<constructor-arg value="classpath:org/example/xsl/transform.xsl"/>
<constructor-arg>
<bean class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>
</constructor-arg>
</bean>
從 Spring Integration 3.0 開始,您可以使用建構函式引數指定轉換器工廠類別名稱。當您使用命名空間時,可以使用 transformer-factory-class
屬性來執行此操作。
使用 ResultTransformer
實作
MarshallingTransformer
和 XsltPayloadTransformer
都允許您指定 ResultTransformer
。因此,如果組譯或 XSLT 轉換傳回 Result
,您可以選擇使用 ResultTransformer
將 Result
轉換為另一種格式。Spring Integration 提供了兩個具體的 ResultTransformer
實作
預設情況下,MarshallingTransformer
始終傳回 Result
。透過指定 ResultTransformer
,您可以自訂傳回的酬載類型。
對於 XsltPayloadTransformer
,行為稍微複雜一些。預設情況下,如果輸入酬載是 String
或 Document
的實例,則會忽略 resultTransformer
屬性。
但是,如果輸入酬載是 Source
或任何其他類型,則會套用 resultTransformer
屬性。此外,您可以將 alwaysUseResultFactory
屬性設定為 true
,這也會導致使用指定的 resultTransformer
。
如需更多資訊和範例,請參閱 命名空間設定和結果轉換器。
XML 轉換器的命名空間支援
Spring Integration XML 命名空間中提供了所有 XML 轉換器的命名空間支援,其範本如 先前所示。轉換器的命名空間支援會根據提供的輸入通道類型建立 EventDrivenConsumer
或 PollingConsumer
的實例。命名空間支援旨在透過允許建立使用一個元素的端點和轉換器來減少 XML 設定量。
使用 UnmarshallingTransformer
以下顯示 UnmarshallingTransformer
的命名空間支援。由於命名空間建立端點實例而不是轉換器,因此您可以將 poller 巢狀於元素內,以控制輸入通道的輪詢。以下範例示範如何執行此操作
<int-xml:unmarshalling-transformer id="defaultUnmarshaller"
input-channel="input" output-channel="output"
unmarshaller="unmarshaller"/>
<int-xml:unmarshalling-transformer id="unmarshallerWithPoller"
input-channel="input" output-channel="output"
unmarshaller="unmarshaller">
<int:poller fixed-rate="2000"/>
<int-xml:unmarshalling-transformer/>
使用 MarshallingTransformer
組譯轉換器的命名空間支援需要 input-channel
、output-channel
和對 marshaller
的參考。您可以使用選用的 result-type
屬性來控制建立的結果類型。有效值為 StringResult
或 DomResult
(預設值)。以下範例設定一個組譯轉換器
<int-xml:marshalling-transformer
input-channel="marshallingTransformerStringResultFactory"
output-channel="output"
marshaller="marshaller"
result-type="StringResult" />
<int-xml:marshalling-transformer
input-channel="marshallingTransformerWithResultTransformer"
output-channel="output"
marshaller="marshaller"
result-transformer="resultTransformer" />
<bean id="resultTransformer" class="o.s.i.xml.transformer.ResultToStringTransformer"/>
如果提供的結果類型不足,您可以提供對 ResultFactory
的自訂實作的參考,以取代使用 result-type
屬性,方法是使用 result-factory
屬性。result-type
和 result-factory
屬性是互斥的。
在內部,StringResult 和 DomResult 結果類型由 ResultFactory 實作表示:StringResultFactory 和 DomResultFactory 。 |
使用 XsltPayloadTransformer
XsltPayloadTransformer
的命名空間支援讓您可以傳入 Resource
(為了建立 Templates
實例),或傳入預先建立的 Templates
實例作為參考。與組譯轉換器一樣,您可以透過指定 result-factory
或 result-type
屬性來控制結果輸出的類型。當您需要在傳送之前轉換結果時,可以使用 result-transformer
屬性來參考 ResultTransformer
的實作。
如果您指定 result-factory 或 result-type 屬性,則 XsltPayloadTransformer 上的 alwaysUseResultFactory 屬性會由 XsltPayloadTransformerParser 設定為 true 。 |
以下範例設定兩個 XSLT 轉換器
<int-xml:xslt-transformer id="xsltTransformerWithResource"
input-channel="withResourceIn" output-channel="output"
xsl-resource="org/springframework/integration/xml/config/test.xsl"/>
<int-xml:xslt-transformer id="xsltTransformerWithTemplatesAndResultTransformer"
input-channel="withTemplatesAndResultTransformerIn" output-channel="output"
xsl-templates="templates"
result-transformer="resultTransformer"/>
您可能需要存取 Message
資料,例如 Message
標頭,才能協助進行轉換。例如,您可能需要存取某些 Message
標頭並將它們作為參數傳遞給轉換器(例如,transformer.setParameter(..)
)。Spring Integration 提供了兩種方便的方法來完成此操作,如以下範例所示
<int-xml:xslt-transformer id="paramHeadersCombo"
input-channel="paramHeadersComboChannel" output-channel="output"
xsl-resource="classpath:transformer.xslt"
xslt-param-headers="testP*, *foo, bar, baz">
<int-xml:xslt-param name="helloParameter" value="hello"/>
<int-xml:xslt-param name="firstName" expression="headers.fname"/>
</int-xml:xslt-transformer>
如果訊息標頭名稱與參數名稱一對一符合,您可以使用 xslt-param-headers
屬性。在其中,您可以使用萬用字元進行簡單的模式比對。它支援以下簡單的模式樣式:xxx*
、xxx
、*xxx
和 xxx*yyy
。
您也可以使用 <xslt-param/>
元素設定個別的 XSLT 參數。在該元素上,您可以設定 expression
屬性或 value
屬性。expression
屬性應該是任何有效的 SpEL 運算式,其中 Message
是運算式評估內容的根物件。value
屬性(與 Spring Bean 中的任何 value
一樣)讓您可以指定簡單的純量值。您也可以使用屬性預留位置(例如 ${some.value}
)。因此,透過 expression
和 value
屬性,您可以將 XSLT 參數對應到 Message
的任何可存取部分以及任何常值。
從 Spring Integration 3.0 開始,您現在可以透過設定 transformer-factory-class
屬性來指定轉換器工廠類別名稱。
命名空間設定和結果轉換器
我們在 使用 ResultTransformer
實作 中涵蓋了使用結果轉換器。本節中的範例使用 XML 命名空間設定來說明幾個特殊的使用案例。首先,我們定義 ResultTransformer
,如以下範例所示
<beans:bean id="resultToDoc" class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>
此 ResultTransformer
接受 StringResult
或 DOMResult
作為輸入,並將輸入轉換為 Document
。
現在我們可以宣告轉換器,如下所示
<int-xml:xslt-transformer input-channel="in" output-channel="fahrenheitChannel"
xsl-resource="classpath:noop.xslt" result-transformer="resultToDoc"/>
如果傳入訊息的酬載類型為 Source
,則第一步是使用 ResultFactory
判斷 Result
。由於我們未指定 ResultFactory
,因此使用預設的 DomResultFactory
,這表示轉換會產生 DomResult
。
但是,由於我們指定了 ResultTransformer
,因此會使用它,且產生的 Message
酬載類型為 Document
。
對於 String 或 Document 酬載,會忽略指定的 ResultTransformer 。如果傳入訊息的酬載類型為 String ,則 XSLT 轉換後的酬載為 String 。同樣地,如果傳入訊息的酬載類型為 Document ,則 XSLT 轉換後的酬載為 Document 。 |
如果訊息酬載不是 Source
、String
或 Document
,作為後備選項,我們會嘗試使用預設的 SourceFactory
建立 Source
。由於我們未使用 source-factory
屬性明確指定 SourceFactory
,因此會使用預設的 DomSourceFactory
。如果成功,則會執行 XSLT 轉換,如同酬載類型為 Source
一樣,如前幾段所述。
DomSourceFactory 支援從 Document 、File 或 String 酬載建立 DOMSource 。 |
下一個轉換器宣告新增了一個 result-type
屬性,該屬性使用 StringResult
作為其值。result-type
在內部由 StringResultFactory
表示。因此,您也可以新增對 StringResultFactory
的參考,方法是使用 result-factory
屬性,這會是相同的。以下範例顯示該轉換器宣告
<int-xml:xslt-transformer input-channel="in" output-channel="fahrenheitChannel"
xsl-resource="classpath:noop.xslt" result-transformer="resultToDoc"
result-type="StringResult"/>
由於我們使用 ResultFactory
,因此 XsltPayloadTransformer
類別的 alwaysUseResultFactory
屬性會隱含地設定為 true
。因此,會使用參考的 ResultToDocumentTransformer
。
因此,如果您轉換類型為 String
的酬載,則產生的酬載類型為 Document
。
[[xsltpayloadtransformer-and-<xsl:output-method=-text-/>]] === XsltPayloadTransformer
和 <xsl:output method="text"/>
<xsl:output method="text"/>
告知 XSLT 範本僅從輸入來源產生文字內容。在這種特殊情況下,我們沒有理由使用 DomResult
。因此,如果基礎 javax.xml.transform.Transformer
的 輸出屬性 稱為 method
,則 XsltPayloadTransformer
預設為 StringResult
。此強制轉換獨立於輸入酬載類型執行。只有在您為 <int-xml:xslt-transformer>
元件設定 result-type
屬性或 result-factory
屬性時,此行為才可用。