转换 XML 有效负载

本节介绍如何转换 XML 负载spring-doc.cn

将 Transformer 配置为 Bean

本节将解释以下转换器的工作原理以及如何将它们配置为 bean:spring-doc.cn

所有 XML 转换器都扩展了 AbstractTransformerAbstractPayloadTransformer,因此实现了 Transformer。 在 Spring 集成中将 XML 转换器配置为 bean 时,通常会将它与MessageTransformingHandler一起配置。 这允许将转换器用作终端节点。 最后,我们讨论命名空间支持,它允许将转换器配置为 XML 中的元素。Transformerspring-doc.cn

解组转换器

UnmarshallingTransformer 允许使用 Spring OXM 的实现对 XML 进行解组。 Spring 的 Object/XML Mapping 支持提供了多种实现,这些实现通过使用 JAXBCastorJiBX 等支持编组和解组。 解组器需要 的实例。 如果消息有效负载不是 的实例,则仍会尝试进行转换。 目前支持 、 、 和 payloads。 要创建到 的自定义转换,您可以注入 SourceFactory 的实现。SourceUnmarshallerSourceSourceStringFilebyte[]org.w3c.dom.DocumentSourcespring-doc.cn

如果未显式设置,则默认情况下,该属性将设置为DomSourceFactorySourceFactoryUnmarshallingTransformer

从版本 5.0 开始,还支持 作为传入的有效负载。 当我们通过 SOAP 收到带有 MTOM 附件的原始文件时,这可能很有用。 有关更多信息,请参阅 MTOM 支持UnmarshallingTransformerorg.springframework.ws.mime.MimeMessageWebServiceMessagespring-doc.cn

以下示例显示如何定义解组转换器:spring-doc.cn

<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 将对象图转换为 XML。 默认情况下,会返回一个 . 但是,您可以通过配置替代项来控制结果的类型,例如 . 在许多情况下,将有效负载转换为替代 XML 格式会更方便。 为此,请配置 . Spring 集成提供了两种实现,一种是转换为 ,另一种是转换为 。 下面的示例配置一个转换为文档的编组转换器:MarshallerMarshallingTransformerDomResultResultFactoryStringResultFactoryResultTransformerStringDocumentspring-doc.cn

<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>

默认情况下,会将 payload 对象传递给 . 但是,如果其 boolean 属性设置为 ,则整个实例将传递给 。 这对于接口的某些自定义实现可能很有用,但通常,当您委托给各种实现中的任何一个时,有效负载是用于封送的适当源对象。MarshallingTransformerMarshallerextractPayloadfalseMessageMarshallerMarshallerMarshallerspring-doc.cn

XsltPayloadTransformer

XsltPayloadTransformer 使用可扩展样式表语言转换 (XSLT) 转换 XML 负载。 转换器的构造函数需要传入 ResourceTemplates 的实例。 传入实例允许对用于创建模板实例的 进行更好的配置。TemplatesTransformerFactoryspring-doc.cn

UnmarshallingTransformer 一样,它会对 的实例执行实际的 XSLT 转换。 因此,如果消息有效负荷不是 的实例,则仍会尝试进行转换。 和 payloads 直接支持。XsltPayloadTransformerSourceSourceStringDocumentspring-doc.cn

要创建到 的自定义转换,您可以注入 SourceFactory 的实现。Sourcespring-doc.cn

如果未显式设置a,则默认情况下,该上的属性设置为DomSourceFactorySourceFactoryXsltPayloadTransformer

默认情况下,会创建一条带有 Result 负载的消息,类似于 . 您可以通过提供 ResultFactoryResultTransformer 来自定义它。XsltPayloadTransformerXmlPayloadMarshallingTransformerspring-doc.cn

以下示例配置一个用作 XSLT 有效负载转换器的 Bean:spring-doc.cn

<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 开始,你可以使用构造函数参数来指定转换器工厂类名。 您可以在使用 namespace 时使用 attribute 来执行此操作。transformer-factory-classspring-doc.cn

使用实现ResultTransformer

和 都允许您指定 ResultTransformer。 因此,如果封送处理或 XSLT 转换返回 Result,则还可以选择使用 a 将其转换为另一种格式。 Spring 集成提供了两个具体的实现:MarshallingTransformerXsltPayloadTransformerResultTransformerResultResultTransformerspring-doc.cn

默认情况下,始终返回 Result。 通过指定 ,您可以自定义返回的负载类型。MarshallingTransformerResultTransformerspring-doc.cn

对于 . 默认情况下,如果输入有效负载是 或 Document 的实例,则会忽略该属性。XsltPayloadTransformerStringresultTransformerspring-doc.cn

但是,如果输入负载是 Source 或任何其他类型,则会应用该属性。 此外,您还可以将该属性设置为 ,这也会导致使用指定的 。resultTransformeralwaysUseResultFactorytrueresultTransformerspring-doc.cn

有关更多信息和示例,请参阅命名空间配置和结果转换器spring-doc.cn

XML 转换器的命名空间支持

Spring 集成 XML 名称空间中提供了对所有 XML 转换器的名称空间支持,前面显示了该名称空间的模板。 对 transformers 的命名空间支持根据提供的输入通道的类型创建 or 的实例。 命名空间支持旨在通过允许创建使用一个元素的端点和转换器来减少 XML 配置的数量。EventDrivenConsumerPollingConsumerspring-doc.cn

使用UnmarshallingTransformer

命名空间支持 如下所示。 由于命名空间创建的是端点实例而不是转换器,因此您可以在元素中嵌套 Poller 来控制 input 通道的轮询。 以下示例显示了如何执行此操作:UnmarshallingTransformerspring-doc.cn

<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

编组转换器的命名空间支持需要 、 、 和对 的引用 。 您可以使用 optional 属性来控制创建的结果类型。 有效值为 or(默认值)。 以下示例配置编组转换器:input-channeloutput-channelmarshallerresult-typeStringResultDomResultspring-doc.cn

<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"/>

如果提供的结果类型不够用,则可以提供对自定义实现的引用,作为使用该属性设置属性的替代方法。 和 属性是互斥的。ResultFactoryresult-typeresult-factoryresult-typeresult-factoryspring-doc.cn

在内部,和 result 类型分别由实现 StringResultFactoryDomResultFactory 表示。StringResultDomResultResultFactory

使用XsltPayloadTransformer

的命名空间支持允许您传入 (以创建 Templates 实例) 或传入预先创建的实例作为引用。 与封送转换器一样,您可以通过指定 the 或 属性来控制结果输出的类型。 当您需要在发送之前转换结果时,您可以使用属性来引用 .XsltPayloadTransformerResourceTemplatesresult-factoryresult-typeresult-transformerResultTransformerspring-doc.cn

如果指定 或 属性,则基础 XsltPayloadTransformer 上的属性将由 XsltPayloadTransformerParser 设置为。result-factoryresult-typealwaysUseResultFactorytrue

以下示例配置两个 XSLT 转换器:spring-doc.cn

<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"/>

您可能需要有权访问数据(如标题),以便协助进行转换。 例如,您可能需要访问某些标头并将它们作为参数传递给转换器(例如,)。 Spring 集成提供了两种便捷的方法来实现这一目标,如下例所示:MessageMessageMessagetransformer.setParameter(..)spring-doc.cn

<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>

如果消息标头名称与参数名称一一匹配,则可以使用该属性。 在该文档中,您可以使用通配符进行简单的模式匹配。 它支持以下简单模式样式:、、*xxx 和 .xslt-param-headersxxx*xxxxxx*yyyspring-doc.cn

您还可以使用 element. 在该元素上,您可以设置 attribute 或 attribute。 该属性应该是任何有效的 SPEL 表达式,并且是表达式评估上下文的根对象。 该属性(与 Spring bean 中的 any 一样)允许您指定简单的标量值。 您还可以使用属性占位符(如 )。 因此,使用 和 属性,您可以将 XSLT 参数映射到 的任何可访问部分以及任何文本值。<xslt-param/>expressionvalueexpressionMessagevaluevalue${some.value}expressionvalueMessagespring-doc.cn

从 Spring Integration 3.0 开始,你现在可以通过设置属性来指定 transformer 工厂类名。transformer-factory-classspring-doc.cn

命名空间配置和结果转换器

我们在 使用 ResultTransformer 实现 中介绍了如何使用结果转换器。 本节中的示例使用 XML 命名空间配置来说明几个特殊用例。 首先,我们定义 ,如下例所示:ResultTransformerspring-doc.cn

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

这将接受 a 或 a 作为输入,并将输入转换为 .ResultTransformerStringResultDOMResultDocumentspring-doc.cn

现在我们可以声明 transformer,如下所示:spring-doc.cn

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

如果传入消息的 payload 类型为 ,则第一步是使用 来确定的。 由于我们没有指定 a ,因此使用默认值,这意味着转换产生 .SourceResultResultFactoryResultFactoryDomResultFactoryDomResultspring-doc.cn

但是,由于我们指定了 ,因此会使用它,并且生成的有效负载是 类型。ResultTransformerMessageDocumentspring-doc.cn

指定的 is ignored with or payloads. 如果传入消息的有效负载是 type ,则 XSLT 转换后的有效负载为 . 同样,如果传入消息的有效负载是 type ,则 XSLT 转换后的有效负载为 'Document'。ResultTransformerStringDocumentStringStringDocument

如果消息有效负载不是 a 、 a 或 a 作为回退选项,我们尝试使用默认的 SourceFactory 创建“Source”。 由于我们没有使用该属性显式指定,因此使用默认的 DomSourceFactory。 如果成功,则执行 XSLT 转换,就像有效负载的类型为 ,如前面段落所述。SourceStringDocumentSourceFactorysource-factorySourcespring-doc.cn

支持从 、 a 或 有效负荷 创建 。DomSourceFactoryDOMSourceDocumentFileString

下一个 transformer 声明添加一个用作其值的属性。 在内部由 . 因此,您还可以使用 attribute 添加对 , 的引用,该属性本来是相同的。 以下示例显示了 transformer 声明:result-typeStringResultresult-typeStringResultFactoryStringResultFactoryresult-factoryspring-doc.cn

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

因为我们使用 a ,所以类的属性被隐式设置为 。 因此,使用引用的 .ResultFactoryalwaysUseResultFactoryXsltPayloadTransformertrueResultToDocumentTransformerspring-doc.cn

因此,如果转换 类型的有效负载 ,则生成的有效负载为 Document 类型。Stringspring-doc.cn

[[xsltpayloadtransformer-and-<xsl:output-method=-text-/>]] === 和XsltPayloadTransformer<xsl:output method="text"/>spring-doc.cn

<xsl:output method="text"/>指示 XSLT 模板仅从输入源生成文本内容。 在这种特殊情况下,我们没有理由使用 . 因此, XsltPayloadTransformer 默认为如果调用的基础的 output 属性返回 。 此强制执行独立于入站有效负载类型。 只有您设置组件的 if 属性或属性时,此行为才可用。DomResultStringResultmethodjavax.xml.transform.Transformertextresult-typeresult-factory<int-xml:xslt-transformer>spring-doc.cn