转换 XML 有效负载
本节介绍如何转换 XML 负载
将 Transformer 配置为 Bean
本节将解释以下转换器的工作原理以及如何将它们配置为 bean:
所有 XML 转换器都扩展了 AbstractTransformer
或 AbstractPayloadTransformer
,因此实现了 Transformer
。
在 Spring 集成中将 XML 转换器配置为 bean 时,通常会将它与MessageTransformingHandler
一起配置。
这允许将转换器用作终端节点。
最后,我们讨论命名空间支持,它允许将转换器配置为 XML 中的元素。Transformer
解组转换器
UnmarshallingTransformer
允许使用 Spring OXM 的实现对 XML 进行解组。
Spring 的 Object/XML Mapping 支持提供了多种实现,这些实现通过使用 JAXB、Castor、JiBX 等支持编组和解组。
解组器需要 的实例。
如果消息有效负载不是 的实例,则仍会尝试进行转换。
目前支持 、 、 和 payloads。
要创建到 的自定义转换,您可以注入 SourceFactory
的实现。Source
Unmarshaller
Source
Source
String
File
byte[]
org.w3c.dom.Document
Source
如果未显式设置,则默认情况下,该属性将设置为DomSourceFactory 。SourceFactory UnmarshallingTransformer |
从版本 5.0 开始,还支持 作为传入的有效负载。
当我们通过 SOAP 收到带有 MTOM 附件的原始文件时,这可能很有用。
有关更多信息,请参阅 MTOM 支持。UnmarshallingTransformer
org.springframework.ws.mime.MimeMessage
WebServiceMessage
以下示例显示如何定义解组转换器:
<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 集成提供了两种实现,一种是转换为 ,另一种是转换为 。
下面的示例配置一个转换为文档的编组转换器:Marshaller
MarshallingTransformer
DomResult
ResultFactory
StringResultFactory
ResultTransformer
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>
默认情况下,会将 payload 对象传递给 .
但是,如果其 boolean 属性设置为 ,则整个实例将传递给 。
这对于接口的某些自定义实现可能很有用,但通常,当您委托给各种实现中的任何一个时,有效负载是用于封送的适当源对象。MarshallingTransformer
Marshaller
extractPayload
false
Message
Marshaller
Marshaller
Marshaller
XsltPayloadTransformer
XsltPayloadTransformer
使用可扩展样式表语言转换 (XSLT) 转换 XML 负载。
转换器的构造函数需要传入 Resource 或 Templates 的实例。
传入实例允许对用于创建模板实例的 进行更好的配置。Templates
TransformerFactory
与 UnmarshallingTransformer
一样,它会对 的实例执行实际的 XSLT 转换。
因此,如果消息有效负荷不是 的实例,则仍会尝试进行转换。 和 payloads 直接支持。XsltPayloadTransformer
Source
Source
String
Document
要创建到 的自定义转换,您可以注入 SourceFactory
的实现。Source
如果未显式设置a,则默认情况下,该上的属性设置为DomSourceFactory 。SourceFactory XsltPayloadTransformer |
默认情况下,会创建一条带有 Result
负载的消息,类似于 .
您可以通过提供 ResultFactory
或 ResultTransformer
来自定义它。XsltPayloadTransformer
XmlPayloadMarshallingTransformer
以下示例配置一个用作 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 开始,你可以使用构造函数参数来指定转换器工厂类名。
您可以在使用 namespace 时使用 attribute 来执行此操作。transformer-factory-class
使用实现ResultTransformer
和 都允许您指定 ResultTransformer
。
因此,如果封送处理或 XSLT 转换返回 Result
,则还可以选择使用 a 将其转换为另一种格式。
Spring 集成提供了两个具体的实现:MarshallingTransformer
XsltPayloadTransformer
ResultTransformer
Result
ResultTransformer
默认情况下,始终返回 Result
。
通过指定 ,您可以自定义返回的负载类型。MarshallingTransformer
ResultTransformer
对于 .
默认情况下,如果输入有效负载是 或 Document
的实例,则会忽略该属性。XsltPayloadTransformer
String
resultTransformer
但是,如果输入负载是 Source
或任何其他类型,则会应用该属性。
此外,您还可以将该属性设置为 ,这也会导致使用指定的 。resultTransformer
alwaysUseResultFactory
true
resultTransformer
有关更多信息和示例,请参阅命名空间配置和结果转换器。
XML 转换器的命名空间支持
Spring 集成 XML 名称空间中提供了对所有 XML 转换器的名称空间支持,前面显示了该名称空间的模板。
对 transformers 的命名空间支持根据提供的输入通道的类型创建 or 的实例。
命名空间支持旨在通过允许创建使用一个元素的端点和转换器来减少 XML 配置的数量。EventDrivenConsumer
PollingConsumer
使用UnmarshallingTransformer
命名空间支持 如下所示。
由于命名空间创建的是端点实例而不是转换器,因此您可以在元素中嵌套 Poller 来控制 input 通道的轮询。
以下示例显示了如何执行此操作: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
编组转换器的命名空间支持需要 、 、 和对 的引用 。
您可以使用 optional 属性来控制创建的结果类型。
有效值为 or(默认值)。
以下示例配置编组转换器: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
在内部,和 result 类型分别由实现 StringResultFactory 和 DomResultFactory 表示。StringResult DomResult ResultFactory |
使用XsltPayloadTransformer
的命名空间支持允许您传入 (以创建 Templates
实例) 或传入预先创建的实例作为引用。
与封送转换器一样,您可以通过指定 the 或 属性来控制结果输出的类型。
当您需要在发送之前转换结果时,您可以使用属性来引用 .XsltPayloadTransformer
Resource
Templates
result-factory
result-type
result-transformer
ResultTransformer
如果指定 或 属性,则基础 XsltPayloadTransformer 上的属性将由 XsltPayloadTransformerParser 设置为。result-factory result-type alwaysUseResultFactory 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"/>
您可能需要有权访问数据(如标题),以便协助进行转换。
例如,您可能需要访问某些标头并将它们作为参数传递给转换器(例如,)。
Spring 集成提供了两种便捷的方法来实现这一目标,如下例所示:Message
Message
Message
transformer.setParameter(..)
<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-headers
xxx*
xxx
xxx*yyy
您还可以使用 element.
在该元素上,您可以设置 attribute 或 attribute。
该属性应该是任何有效的 SPEL 表达式,并且是表达式评估上下文的根对象。
该属性(与 Spring bean 中的 any 一样)允许您指定简单的标量值。
您还可以使用属性占位符(如 )。
因此,使用 和 属性,您可以将 XSLT 参数映射到 的任何可访问部分以及任何文本值。<xslt-param/>
expression
value
expression
Message
value
value
${some.value}
expression
value
Message
从 Spring Integration 3.0 开始,你现在可以通过设置属性来指定 transformer 工厂类名。transformer-factory-class
命名空间配置和结果转换器
我们在 使用 ResultTransformer
实现 中介绍了如何使用结果转换器。
本节中的示例使用 XML 命名空间配置来说明几个特殊用例。
首先,我们定义 ,如下例所示:ResultTransformer
<beans:bean id="resultToDoc" class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>
这将接受 a 或 a 作为输入,并将输入转换为 .ResultTransformer
StringResult
DOMResult
Document
现在我们可以声明 transformer,如下所示:
<int-xml:xslt-transformer input-channel="in" output-channel="fahrenheitChannel"
xsl-resource="classpath:noop.xslt" result-transformer="resultToDoc"/>
如果传入消息的 payload 类型为 ,则第一步是使用 来确定的。
由于我们没有指定 a ,因此使用默认值,这意味着转换产生 .Source
Result
ResultFactory
ResultFactory
DomResultFactory
DomResult
但是,由于我们指定了 ,因此会使用它,并且生成的有效负载是 类型。ResultTransformer
Message
Document
指定的 is ignored with or payloads.
如果传入消息的有效负载是 type ,则 XSLT 转换后的有效负载为 .
同样,如果传入消息的有效负载是 type ,则 XSLT 转换后的有效负载为 'Document'。ResultTransformer String Document String String Document |
如果消息有效负载不是 a 、 a 或 a 作为回退选项,我们尝试使用默认的 SourceFactory
创建“Source”。
由于我们没有使用该属性显式指定,因此使用默认的 DomSourceFactory
。
如果成功,则执行 XSLT 转换,就像有效负载的类型为 ,如前面段落所述。Source
String
Document
SourceFactory
source-factory
Source
支持从 、 a 或 有效负荷 创建 。DomSourceFactory DOMSource Document File String |
下一个 transformer 声明添加一个用作其值的属性。
在内部由 .
因此,您还可以使用 attribute 添加对 , 的引用,该属性本来是相同的。
以下示例显示了 transformer 声明: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"/>
因为我们使用 a ,所以类的属性被隐式设置为 。
因此,使用引用的 .ResultFactory
alwaysUseResultFactory
XsltPayloadTransformer
true
ResultToDocumentTransformer
因此,如果转换 类型的有效负载 ,则生成的有效负载为 Document
类型。String
[[xsltpayloadtransformer-and-<xsl:output-method=-text-/>]]
=== 和XsltPayloadTransformer
<xsl:output method="text"/>
<xsl:output method="text"/>
指示 XSLT 模板仅从输入源生成文本内容。
在这种特殊情况下,我们没有理由使用 .
因此, XsltPayloadTransformer
默认为如果调用的基础的 output 属性返回 。
此强制执行独立于入站有效负载类型。
只有您设置组件的 if 属性或属性时,此行为才可用。DomResult
StringResult
method
javax.xml.transform.Transformer
text
result-type
result-factory
<int-xml:xslt-transformer>