轉換 XML 有效負載

本節介紹如何轉換XML負載

配置作為Bean的轉換器

本節將解釋以下轉換器的工作原理以及如何將其配置為Bean

所有XML轉換器都繼承自 AbstractTransformerAbstractPayloadTransformer,因此實現了 Transformer。在Spring Integration中將XML轉換器配置為Bean時,通常會將 TransformerMessageTransformingHandler 結合配置。這允許轉換器用作端點。最後,我們將討論名稱空間支援,它允許將轉換器配置為XML中的元素。

UnmarshallingTransformer

UnmarshallingTransformer 允許使用 Spring OXM Unmarshaller 的實現來解組XML Source。Spring的物件/XML對映支援提供了多種實現,它們支援使用 JAXBCastorJiBX 等進行編組和解組。解組器需要一個 Source 例項。如果訊息負載不是 Source 例項,則仍會嘗試轉換。目前,支援 StringFilebyte[]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負載。轉換器的建構函式需要傳入 ResourceTemplates 的例項。傳入 Templates 例項可以更靈活地配置用於建立模板例項的 TransformerFactory

UnmarshallingTransformer 一樣,XsltPayloadTransformerSource 例項執行實際的XSLT轉換。因此,如果訊息負載不是 Source 例項,則仍會嘗試轉換。直接支援 StringDocument 負載。

要建立自定義的 Source 轉換,您可以注入 SourceFactory 的實現。

如果未顯式設定 SourceFactory,則 XsltPayloadTransformer 上的屬性預設設定為 DomSourceFactory

預設情況下,XsltPayloadTransformer 建立一個帶有 Result 負載的訊息,類似於 XmlPayloadMarshallingTransformer。您可以透過提供 ResultFactoryResultTransformer 來定製此行為。

以下示例配置了一個作為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 實現

MarshallingTransformerXsltPayloadTransformer 都允許您指定 ResultTransformer。因此,如果編組或XSLT轉換返回 Result,您可以選擇也使用 ResultTransformerResult 轉換為另一種格式。Spring Integration提供了兩個具體的 ResultTransformer 實現

預設情況下,MarshallingTransformer 總是返回一個 Result。透過指定 ResultTransformer,您可以自定義返回的負載型別。

對於 XsltPayloadTransformer,行為略微複雜。預設情況下,如果輸入負載是 StringDocument 的例項,則 resultTransformer 屬性將被忽略。

但是,如果輸入負載是 Source 或任何其他型別,則會應用 resultTransformer 屬性。此外,您可以將 alwaysUseResultFactory 屬性設定為 true,這也會導致使用指定的 resultTransformer

有關更多資訊和示例,請參閱 名稱空間配置和結果轉換器

XML轉換器的名稱空間支援

所有XML轉換器的名稱空間支援都在Spring Integration XML名稱空間中提供,其模板 之前已顯示。轉換器的名稱空間支援根據所提供輸入通道的型別建立 EventDrivenConsumerPollingConsumer 例項。名稱空間支援旨在透過允許使用一個元素建立端點和轉換器來減少XML配置的數量。

使用 UnmarshallingTransformer

下面顯示了 UnmarshallingTransformer 的名稱空間支援。由於名稱空間建立的是端點例項而不是轉換器,您可以在元素中巢狀一個輪詢器以控制輸入通道的輪詢。以下示例顯示瞭如何操作

<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-channeloutput-channel 和對 marshaller 的引用。您可以使用可選的 result-type 屬性來控制建立的結果型別。有效值為 StringResultDomResult(預設值)。以下示例配置了一個編組轉換器

<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-factory 屬性設定 result-type 屬性的替代方案。result-typeresult-factory 屬性互斥。

在內部,StringResultDomResult 結果型別分別由 ResultFactory 實現:StringResultFactoryDomResultFactory 表示。

使用 XsltPayloadTransformer

XsltPayloadTransformer 的名稱空間支援允許您傳入 Resource(以便建立 Templates 例項)或傳入預先建立的 Templates 例項作為引用。與編組轉換器一樣,您可以透過指定 result-factoryresult-type 屬性來控制結果輸出的型別。當您需要在傳送之前轉換結果時,可以使用 result-transformer 屬性來引用 ResultTransformer 的實現。

如果您指定 result-factoryresult-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**xxxxxx*yyy

您還可以使用 <xslt-param/> 元素配置單個XSLT引數。在該元素上,您可以設定 expression 屬性或 value 屬性。expression 屬性應該是任何有效的SpEL表示式,其中 Message 是表示式評估上下文的根物件。value 屬性(與Spring Bean中的任何 value 一樣)允許您指定簡單的標量值。您還可以使用屬性佔位符(例如 ${some.value})。因此,透過 expressionvalue 屬性,您可以將XSLT引數對映到 Message 的任何可訪問部分以及任何字面值。

從Spring Integration 3.0開始,您現在可以透過設定 transformer-factory-class 屬性來指定轉換器工廠類名。

名稱空間配置和結果轉換器

我們在 使用 ResultTransformer 實現 中介紹了結果轉換器的使用。本節中的示例使用XML名稱空間配置來演示幾個特殊用例。首先,我們定義 ResultTransformer,如下例所示

<beans:bean id="resultToDoc" class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>

ResultTransformer 接受 StringResultDOMResult 作為輸入,並將輸入轉換為 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,它將被使用,並且生成的訊息負載型別為 Document

對於 StringDocument 負載,指定的 ResultTransformer 將被忽略。如果傳入訊息的負載型別是 String,則XSLT轉換後的負載是 String。類似地,如果傳入訊息的負載型別是 Document,則XSLT轉換後的負載是 Document

如果訊息負載不是 SourceStringDocument,作為備用選項,我們嘗試使用預設的 SourceFactory 建立 Source。由於我們沒有透過 source-factory 屬性顯式指定 SourceFactory,因此使用預設的 DomSourceFactory。如果成功,則執行XSLT轉換,就好像負載型別是 Source 一樣,如前幾段所述。

DomSourceFactory 支援從 DocumentFileString 負載建立 DOMSource

下一個轉換器宣告添加了一個 result-type 屬性,其值為 StringResultresult-type 在內部由 StringResultFactory 表示。因此,您也可以透過使用 result-factory 屬性新增對 StringResultFactory 的引用,結果將是相同的。以下示例顯示了該轉換器宣告

<int-xml:xslt-transformer input-channel="in" output-channel="fahrenheitChannel"
		xsl-resource="classpath:noop.xslt" result-transformer="resultToDoc"
		result-type="StringResult"/>

由於我們使用了 ResultFactoryXsltPayloadTransformer 類的 alwaysUseResultFactory 屬性被隱式設定為 true。因此,引用的 ResultToDocumentTransformer 將被使用。

因此,如果您轉換型別為 String 的負載,則生成的負載型別為 Document

XsltPayloadTransformer<xsl:output method="text"/>

<xsl:output method="text"/> 告訴XSLT模板僅從輸入源生成文字內容。在這種特殊情況下,我們沒有理由使用 DomResult。因此,如果底層 javax.xml.transform.Transformer輸出屬性 中名為 method 的屬性返回 text,則 XsltPayloadTransformer 預設使用 StringResult。此強制轉換與入站負載型別無關。此行為僅在為 <int-xml:xslt-transformer> 元件設定了 result-type 屬性或 result-factory 屬性時可用。

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