XML 支持 - 处理 XML 有效负载
XML 支持 - 处理 XML 有效负载
Spring 集成的 XML 支持通过以下组件扩展了 Spring 集成的核心:
您需要将此依赖项包含在您的项目中:
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-xml</artifactId>
<version>6.0.9</version>
</dependency>
compile "org.springframework.integration:spring-integration-xml:6.0.9"
这些组件使在 Spring Integration 中处理 XML 消息变得更加简单。
消息收发组件使用以多种格式表示的 XML,包括 、 和 的实例。
但是,如果需要 DOM 表示形式(例如,为了评估 XPath 表达式),则有效负载将转换为所需的类型,然后转换回 .
需要实例的组件将创建一个命名空间感知实例(如果您未提供实例)。
当您需要更好地控制文档创建时,可以提供适当配置的 实例。java.lang.String
org.w3c.dom.Document
javax.xml.transform.Source
String
String
DocumentBuilder
DocumentBuilder
命名空间支持
Spring 集成 XML 模块中的所有组件都提供名称空间支持。 为了启用名称空间支持,你需要导入 Spring 集成 XML 模块的模式。 以下示例显示了一个典型的设置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-xml="http://www.springframework.org/schema/integration/xml"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/xml
https://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd">
</beans>
XPath 表达式
Spring 集成 XML 模块中的许多组件都可以使用 XPath 表达式。
这些组件中的每一个要么引用已定义为顶级元素的 XPath 表达式,要么使用嵌套元素。<xpath-expression/>
所有形式的 XPath 表达式都会导致创建使用 Spring 的 an 。
创建 XPath 表达式时,将使用 Classpath 上可用的最佳 XPath 实现(JAXP 1.3+ 或 Jaxen,首选 JAXP)。XPathExpression
org.springframework.xml.xpath.XPathExpressionFactory
在内部, Spring 集成使用 Spring Web Services 项目 (https://www.spring.io/spring-ws) 提供的 XPath 功能。 具体来说,我们使用 Spring Web Services XML 模块 (spring-xml-x.x.x.jar)。 要更深入地了解,请参阅 https://docs.spring.io/spring-ws/docs/current/reference/#xpath 中的相应文档。 |
以下是元素的所有可用配置参数的概述:
下面的清单显示了该元素的可用属性:xpath-expression
xpath-expression
<int-xml:xpath-expression expression="" (1)
id="" (2)
namespace-map="" (3)
ns-prefix="" (4)
ns-uri=""> (5)
<map></map> (6)
</int-xml:xpath-expression>
1 | 定义 XPath 表达式。 必填。 |
2 | 基础 Bean 定义的标识符。
它是 的实例。
自选。org.springframework.xml.xpath.XPathExpression |
3 | 对包含命名空间的映射的引用。
映射的键定义命名空间前缀,映射的值设置命名空间 URI。
同时指定此属性和元素或 and 属性是无效的。
自选。map ns-prefix ns-uri |
4 | 允许您将命名空间前缀直接设置为 XPath 表达式元素上的属性。
如果设置了 ,则还必须设置该属性。
自选。ns-prefix ns-uri |
5 | 允许您直接将命名空间 URI 设置为 XPath 表达式元素上的属性。
如果设置了 ,则还必须设置该属性。
自选。ns-uri ns-prefix |
6 | 定义包含命名空间的映射。
只允许一个子元素。
映射的键定义命名空间前缀,映射的值设置命名空间 URI。
同时指定此元素和属性或设置 and 属性都是无效的。
自选。map map ns-prefix ns-uri |
为 XPath 表达式提供命名空间(可选)
对于 XPath 表达式元素,您可以提供名称空间信息作为配置参数。 您可以使用以下选项之一来定义命名空间:
-
使用属性
namespace-map
-
使用 sub 元素提供命名空间的映射
map
-
指定 and 属性
ns-prefix
ns-uri
所有三个选项都是互斥的。 只能设置一个选项。
下面的示例显示了使用 XPath 表达式的几种不同方法,包括前面提到的用于设置 XML 命名空间的选项:
<int-xml:xpath-filter id="filterReferencingXPathExpression"
xpath-expression-ref="refToXpathExpression"/>
<int-xml:xpath-expression id="refToXpathExpression" expression="/name"/>
<int-xml:xpath-filter id="filterWithoutNamespace">
<int-xml:xpath-expression expression="/name"/>
</int-xml:xpath-filter>
<int-xml:xpath-filter id="filterWithOneNamespace">
<int-xml:xpath-expression expression="/ns1:name"
ns-prefix="ns1" ns-uri="www.example.org"/>
</int-xml:xpath-filter>
<int-xml:xpath-filter id="filterWithTwoNamespaces">
<int-xml:xpath-expression expression="/ns1:name/ns2:type">
<map>
<entry key="ns1" value="www.example.org/one"/>
<entry key="ns2" value="www.example.org/two"/>
</map>
</int-xml:xpath-expression>
</int-xml:xpath-filter>
<int-xml:xpath-filter id="filterWithNamespaceMapReference">
<int-xml:xpath-expression expression="/ns1:name/ns2:type"
namespace-map="defaultNamespaces"/>
</int-xml:xpath-filter>
<util:map id="defaultNamespaces">
<util:entry key="ns1" value="www.example.org/one"/>
<util:entry key="ns2" value="www.example.org/two"/>
</util:map>
将 XPath 表达式与默认命名空间一起使用
使用默认命名空间时,您可能会遇到行为与预期不同的情况。 假设我们有以下 XML 文档(表示两本书的订单):
<?xml version="1.0" encoding="UTF-8"?>
<order>
<orderItem>
<isbn>0321200683</isbn>
<quantity>2</quantity>
</orderItem>
<orderItem>
<isbn>1590596439</isbn>
<quantity>1</quantity>
</orderItem>
</order>
本文档不声明命名空间。 因此,应用以下 XPath 表达式将按预期工作:
<int-xml:xpath-expression expression="/order/orderItem" />
您可能希望相同的表达式也适用于以下 XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<order xmlns="http://www.example.org/orders">
<orderItem>
<isbn>0321200683</isbn>
<quantity>2</quantity>
</orderItem>
<orderItem>
<isbn>1590596439</isbn>
<quantity>1</quantity>
</orderItem>
</order>
前面的示例看起来与前面的示例完全相同,但声明了一个默认命名空间。
但是,在这种情况下,前面的 XPath 表达式 () 会失败。/order/orderItem
要解决此问题,必须通过设置 and 属性或设置属性来提供命名空间前缀和命名空间 URI。
命名空间 URI 必须与 XML 文档中声明的命名空间匹配。
在前面的示例中,即 。ns-prefix
ns-uri
namespace-map
http://www.example.org/orders
但是,您可以任意选择命名空间前缀。 事实上,提供空字符串实际上是有效的。 (但是,不允许使用 null。 如果命名空间前缀由空字符串组成,则 Xpath 表达式必须使用冒号 (“:”) 来指示默认命名空间。 如果省略冒号,则 XPath 表达式不匹配。 以下 XPath 表达式与前面示例中的 XML 文档匹配:
<int-xml:xpath-expression expression="/:order/:orderItem"
ns-prefix="" ns-uri="https://www.example.org/prodcuts"/>
您还可以提供任何其他任意选择的命名空间前缀。
以下 XPath 表达式(使用命名空间前缀)也匹配:myorder
<int-xml:xpath-expression expression="/myorder:order/myorder:orderItem"
ns-prefix="myorder" ns-uri="https://www.example.org/prodcuts"/>
命名空间 URI 是真正重要的信息,而不是前缀。 Jaxen 很好地总结了这一点:
在 XPath 1.0 中,所有无前缀的名称都是非限定的。 不要求 XPath 表达式中使用的前缀与所查询的文档中使用的前缀相同。 只需要匹配命名空间 URI,不需要匹配前缀。
转换 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
和<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>
使用 XPath 转换 XML 消息
在消息转换方面,XPath 是转换具有 XML 有效负载的消息的好方法。
您可以通过使用 element 定义 XPath 转换器来实现此目的。<xpath-transformer/>
简单的 XPath 转换
请考虑以下转换器配置:
<int-xml:xpath-transformer input-channel="inputChannel" output-channel="outputChannel"
xpath-expression="/person/@name" />
另请考虑以下几点:Message
Message<?> message =
MessageBuilder.withPayload("<person name='John Doe' age='42' married='true'/>").build();
将此消息发送到 'inputChannel' 后,之前配置的 XPath 转换器将此 XML 消息转换为有效负载为 'John Doe' 的简单消息,所有这些都基于属性中指定的简单 XPath 表达式。Message
xpath-expression
XPath 还允许您将提取的元素简单转换为所需的类型。
有效的返回类型在接口指定的转换规则中定义并遵循这些规则。javax.xml.xpath.XPathConstants
javax.xml.xpath.XPath
以下常量由类定义: 、 、 、 、 和 。XPathConstants
BOOLEAN
DOM_OBJECT_MODEL
NODE
NODESET
NUMBER
STRING
您可以使用 element 的属性来配置所需的类型,如下例所示(两次):evaluation-type
<xpath-transformer/>
<int-xml:xpath-transformer input-channel="numberInput" xpath-expression="/person/@age"
evaluation-type="NUMBER_RESULT" output-channel="output"/>
<int-xml:xpath-transformer input-channel="booleanInput"
xpath-expression="/person/@married = 'true'"
evaluation-type="BOOLEAN_RESULT" output-channel="output"/>
节点映射器
如果需要为 XPath 表达式提取的节点提供自定义映射,则可以提供对 (实现用于基于每个节点映射对象的接口)的实现的引用。
要提供对 的引用 ,可以使用 该属性,如下例所示:org.springframework.xml.xpath.NodeMapper
XPathOperations
Node
NodeMapper
node-mapper
<int-xml:xpath-transformer input-channel="nodeMapperInput" xpath-expression="/person/@age"
node-mapper="testNodeMapper" output-channel="output"/>
以下示例显示了与上述示例配合使用的实现:NodeMapper
class TestNodeMapper implements NodeMapper {
public Object mapNode(Node node, int nodeNum) throws DOMException {
return node.getTextContent() + "-mapped";
}
}
XML 负载转换器
您还可以使用 的实现来提供更精细的转换。
以下示例演示如何定义一个:org.springframework.integration.xml.XmlPayloadConverter
<int-xml:xpath-transformer input-channel="customConverterInput"
output-channel="output" xpath-expression="/test/@type"
converter="testXmlPayloadConverter" />
以下示例显示了与上述示例配合使用的实现:XmlPayloadConverter
class TestXmlPayloadConverter implements XmlPayloadConverter {
public Source convertToSource(Object object) {
throw new UnsupportedOperationException();
}
//
public Node convertToNode(Object object) {
try {
return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new InputSource(new StringReader("<test type='custom'/>")));
}
catch (Exception e) {
throw new IllegalStateException(e);
}
}
//
public Document convertToDocument(Object object) {
throw new UnsupportedOperationException();
}
}
如果您未提供此引用,则使用 the。
在大多数情况下,它应该就足够了,因为它可以从 、 和 payload 转换。
如果您需要扩展该默认实现的功能之外,则 upstream 可能比在此处提供对此策略的自定义实现的引用更好。DefaultXmlPayloadConverter
Node
Document
Source
File
String
InputStream
byte[]
Transformer
拆分 XML 消息
XPathMessageSplitter
支持具有 OR 负载的消息。
拆分器使用提供的 XPath 表达式将负载拆分为多个节点。
默认情况下,这会导致每个实例都成为新消息的有效负载。
当每条消息都应该为 时,您可以设置标志。
在传入有效负载的情况下,有效负载将被转换,然后被拆分,然后再转换回多个消息。
XPath 拆分器实现,因此应与适当的端点一起配置(有关更简单的配置替代方案,请参阅以下示例后面的命名空间支持示例)。
以下示例配置一个 bean,该 bean 使用 :String
Document
Node
Document
createDocuments
String
String
MessageHandler
XPathMessageSplitter
<bean id="splittingEndpoint"
class="org.springframework.integration.endpoint.EventDrivenConsumer">
<constructor-arg ref="orderChannel" />
<constructor-arg>
<bean class="org.springframework.integration.xml.splitter.XPathMessageSplitter">
<constructor-arg value="/order/items" />
<property name="documentBuilder" ref="customisedDocumentBuilder" />
<property name="outputChannel" ref="orderItemsChannel" />
</bean>
</constructor-arg>
</bean>
XPath splitter 命名空间支持允许您创建具有 input 通道和 output 通道的消息端点,如下例所示:
<!-- Split the order into items and create a new message for each item node -->
<int-xml:xpath-splitter id="orderItemSplitter"
input-channel="orderChannel"
output-channel="orderItemsChannel">
<int-xml:xpath-expression expression="/order/items"/>
</int-xml:xpath-splitter>
<!-- Split the order into items, create a new document for each item-->
<int-xml:xpath-splitter id="orderItemDocumentSplitter"
input-channel="orderChannel"
output-channel="orderItemsChannel"
create-documents="true">
<int-xml:xpath-expression expression="/order/items"/>
<int:poller fixed-rate="2000"/>
</int-xml:xpath-splitter>
从版本 4.2 开始,当请求不是 type 时,会公开实例的(例如 )属性。
以下示例定义一个属性并将其与该属性一起使用:XPathMessageSplitter
outputProperties
OutputKeys.OMIT_XML_DECLARATION
javax.xml.transform.Transformer
payload
org.w3c.dom.Node
output-properties
<util:properties id="outputProperties">
<beans:prop key="#{T (javax.xml.transform.OutputKeys).OMIT_XML_DECLARATION}">yes</beans:prop>
</util:properties>
<xpath-splitter input-channel="input"
output-properties="outputProperties">
<xpath-expression expression="/orders/order"/>
</xpath-splitter>
从 开始,将选项公开为标志(默认为 )。
这允许在下游流中 “流式处理” 拆分节点。
将 mode 设置为 后,每个节点在迭代时都会变换。
When ,在开始将拆分节点发送到输出通道之前,首先转换所有条目。
(您可以将差异视为“转换、发送、转换、发送”与“转换、转换、发送、发送”。
有关更多信息,请参阅 Splitter 。version 4.2
XPathMessageSplitter
iterator
boolean
true
iterator
true
false
使用 XPath 路由 XML 消息
与基于 SPEL 的路由器类似, Spring 集成提供了对基于 XPath 表达式的路由消息的支持,这允许你创建具有 input 通道但没有输出通道的消息端点。 相反,一个或多个 output channel 是动态确定的。 以下示例说明如何创建此类路由器:
<int-xml:xpath-router id="orderTypeRouter" input-channel="orderChannel">
<int-xml:xpath-expression expression="/order/type"/>
</int-xml:xpath-router>
有关 Router 之间通用属性的概述,请参阅 Common Router Parameters。 |
在内部,XPath 表达式作为 type 计算并转换为表示通道名称的 a。
通常,此类列表包含单个通道名称。
但是,根据 XPath 表达式的结果,如果 XPath 表达式返回多个值,则 XPath 路由器也可以具有收件人列表路由器的特征。
在这种情况下,将包含多个频道名称。
因此,消息将发送到列表中的所有通道。NODESET
List<String>
List<String>
因此,假设传递给以下 router 配置的 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 表达式的默认计算类型是 ,它被转换为通道名称的 a,它处理单通道场景以及多通道场景。NODESET
List<String>
尽管如此,某些 XPath 表达式可能从一开始就计算为 type。
例如,请考虑以下 XPath 表达式:String
name(./node())
此表达式返回根节点的名称。
如果使用的是默认评估类型,则会导致异常。NODESET
对于这些方案,您可以使用 attribute ,它允许您管理评估类型。
这是默认的。
但是,如果将其设置为 ,则使用评估类型。evaluate-as-string
FALSE
TRUE
String
XPath 1.0 指定了 4 种数据类型:
当 XPath Router 使用 optional 属性计算表达式时,返回值由 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>
XML 负载转换器
对于 XPath 路由器,您还可以指定在 XPath 评估之前转换负载时要使用的 Converter。
因此,XPath Router 支持策略的自定义实现,并且在 XML 中配置元素时,可以通过属性提供对此类实现的引用。XmlPayloadConverter
xpath-router
converter
如果未明确提供此引用,则使用 the。
在大多数情况下,它应该足够了,因为它可以从 Node、Document、Source、File 和 String 类型的有效负载进行转换。
如果你需要扩展该默认实现的能力,那么在大多数情况下,上游 Transformer 通常是更好的选择,而不是在此处提供对此策略的自定义实现的引用。DefaultXmlPayloadConverter
XPath 标头扩充器
XPath 报头扩充器定义一个报头扩充器消息转换器,该转换器根据消息有效负荷计算 XPath 表达式,并将计算结果插入到消息报头中。
以下清单显示了所有可用的配置参数:
<int-xml:xpath-header-enricher default-overwrite="true" (1)
id="" (2)
input-channel="" (3)
output-channel="" (4)
should-skip-nulls="true"> (5)
<int:poller></int:poller> (6)
<int-xml:header name="" (7)
evaluation-type="STRING_RESULT" (8)
header-type="int" (9)
overwrite="true" (10)
xpath-expression="" (11)
xpath-expression-ref=""/> (12)
</int-xml:xpath-header-enricher>
1 | 指定是否覆盖现有标头值的默认布尔值。 它仅对不提供自己的 'overwrite' 属性的子元素生效。 如果未设置 'default- overwrite' 属性,则指定的标头值不会覆盖任何具有相同标头名称的现有标头值。 自选。 |
2 | 基础 Bean 定义的 ID。 自选。 |
3 | 此终端节点的接收消息通道。 自选。 |
4 | 将扩充消息发送到的通道。 自选。 |
5 | 指定是否应跳过 null 值,例如可能从表达式计算返回的 null 值。
默认值为 .
如果 null 值应触发删除相应的标头,请将此项设置为 。
自选。true false |
6 | 与 Header Enricher 一起使用的 Poller 。 自选。 |
7 | 要扩充的标头的名称。 命令的。 |
8 | XPath 评估所需的结果类型。
如果未设置属性,则这是标头值的类型。
允许使用以下值: 、 和 。
如果未设置,则它在内部默认为 。
自选。header-type BOOLEAN_RESULT STRING_RESULT NUMBER_RESULT NODE_RESULT NODE_LIST_RESULT XPathEvaluationType.STRING_RESULT |
9 | 标头值类型的完全限定类名。
XPath 评估的结果由 转换为此类型。
例如,这允许将 a (双精度) 转换为 .
该类型可以声明为基元(如 ),但结果始终是等效的包装类(如 )。
有效负载类型转换中讨论的相同集成用于转换,因此通过向服务添加自定义转换器来支持转换为自定义类型。
自选。ConversionService NUMBER_RESULT Integer int Integer ConversionService |
10 | 布尔值,用于指示此报头值是否应覆盖同名的现有报头值(如果 input 中已存在)。Message |
11 | XPath 表达式为 .
您必须设置此属性或两者,但不能同时设置两者。String xpath-expression-ref |
12 | XPath 表达式引用。
您必须设置此属性或两者,但不能同时设置两者。xpath-expression |
使用 XPath 过滤器
此组件定义基于 XPath 的消息过滤器。
在内部,这些组件使用包装 .MessageFilter
AbstractXPathMessageSelector
有关更多详细信息,请参阅筛选器。 |
要使用 XPath 过滤器,您至少必须通过声明元素或在属性中引用 XPath 表达式来提供 XPath 表达式。xpath-expression
xpath-expression-ref
如果提供的 XPath 表达式的计算结果为值,则不需要其他配置参数。
但是,如果 XPath 表达式的计算结果为 ,则应设置与计算结果匹配的属性。boolean
String
match-value
match-type
有三个选项:
-
exact
:对应于 on 。 底层实现使用equals
java.lang.String
StringValueTestXPathMessageSelector
-
case-insensitive
:对应于 on 。 底层实现使用equals-ignore-case
java.lang.String
StringValueTestXPathMessageSelector
-
regex
:匹配操作 1 。 底层实现使用java.lang.String
RegexTestXPathMessageSelector
当提供 'regex' 的 'match-type' 值时,与该属性一起提供的值必须是有效的正则表达式。match-value
以下示例显示了该元素的所有可用属性:xpath-filter
<int-xml:xpath-filter discard-channel="" (1)
id="" (2)
input-channel="" (3)
match-type="exact" (4)
match-value="" (5)
output-channel="" (6)
throw-exception-on-rejection="false" (7)
xpath-expression-ref=""> (8)
<int-xml:xpath-expression ... /> (9)
<int:poller ... /> (10)
</int-xml:xpath-filter>
1 | 消息通道,您希望发送被拒绝的消息。 自选。 |
2 | 基础 Bean 定义的 ID。 自选。 |
3 | 此终端节点的接收消息通道。 自选。 |
4 | 要在 XPath 评估结果和 .
默认值为 .
自选。match-value exact |
5 | 要与 XPath 评估结果匹配的字符串值。 如果未设置此属性,则 XPath 计算必须生成布尔结果。 自选。 |
6 | 将匹配的邮件调度到的通道。 自选。 |
7 | 默认情况下,此属性设置为 ,并且被拒绝的消息(与过滤条件不匹配的消息)将被静默丢弃。
但是,如果设置为 ,则消息拒绝会导致错误情况,并将异常向上游传播到调用方。
自选。false true |
8 | 对要评估的 XPath 表达式实例的引用。 |
9 | 此子元素设置要计算的 XPath 表达式。
如果不包含此元素,则必须设置 该属性。
此外,您只能包含一个元素。xpath-expression-ref xpath-expression |
10 | 用于 XPath 过滤器的 Poller。 自选。 |
#xpath SPEL 函数
Spring 集成,从版本 3.0 开始,提供了内置的 SPEL 函数,该函数调用静态方法。
此方法委托给 .
下面的清单显示了一些使用示例:#xpath
XPathUtils.evaluate(…)
org.springframework.xml.xpath.XPathExpression
<transformer expression="#xpath(payload, '/name')"/>
<filter expression="#xpath(payload, headers.xpath, 'boolean')"/>
<splitter expression="#xpath(payload, '//book', 'document_list')"/>
<router expression="#xpath(payload, '/person/@age', 'number')">
<mapping channel="output1" value="16"/>
<mapping channel="output2" value="45"/>
</router>
还支持第三个可选参数,用于转换 XPath 评估的结果。
它可以是 String 常量 (、 、 、 和 )之一,也可以是一个实例。
默认情况下,SPEL 函数返回 XPath 评估的表示形式。#xpath()
string
boolean
number
node
node_list
document_list
org.springframework.xml.xpath.NodeMapper
#xpath
String
要启用 SPEL 函数,可以将 添加到 Classpath 中。
你不需要从 Spring 集成 XML 名称空间声明任何组件。#xpath spring-integration-xml.jar |
有关详细信息,请参阅“Spring 表达式语言 (SpEL)”。
XML 验证过滤器
XML 验证筛选器允许您根据提供的架构实例验证传入消息。 支持以下 Schema 类型:
-
xml-schema (https://www.w3.org/2001/XMLSchema)
-
relax-ng (https://relaxng.org)
未通过验证的消息可以静默丢弃,也可以转发到可定义的 .
此外,您还可以配置此过滤器以在验证失败时引发 if。discard-channel
Exception
以下清单显示了所有可用的配置参数:
<int-xml:validating-filter discard-channel="" (1)
id="" (2)
input-channel="" (3)
output-channel="" (4)
schema-location="" (5)
schema-type="xml-schema" (6)
throw-exception-on-rejection="false" (7)
xml-converter="" (8)
xml-validator=""> (9)
<int:poller .../> (10)
</int-xml:validating-filter>
1 | 消息通道,您希望发送被拒绝的消息。 自选。 |
2 | 基础 Bean 定义的 ID。 自选。 |
3 | 此终端节点的接收消息通道。 自选。 |
4 | 消息通道,您希望发送接受的消息。 自选。 |
5 | 设置要验证消息有效负载的架构的位置。
内部使用接口。
您可以设置此属性或属性,但不能同时设置两者。
自选。org.springframework.core.io.Resource xml-validator |
6 | 设置 Schema 类型。
可以是 或 。
自选。
如果未设置,则默认为 ,内部转换为 。xml-schema relax-ng xml-schema org.springframework.xml.validation.XmlValidatorFactory#SCHEMA_W3C_XML |
7 | 如果 ,如果提供的 Message 的有效负载验证失败,则抛出 a。
如果未设置,则默认为。
自选。true MessageRejectedException false |
8 | 对自定义策略的引用。
自选。org.springframework.integration.xml.XmlPayloadConverter |
9 | 对自定义策略的引用。
您可以设置此属性或属性,但不能同时设置两者。
自选。sorg.springframework.xml.validation.XmlValidator schema-location |
10 | 用于 XPath 过滤器的 Poller。 自选。 |