当前位置 : 主页 > 编程语言 > java >

Spring 集成对 Web 服务的支持

来源:互联网 收集:自由互联 发布时间:2023-02-04
本章描述了 Spring 集成对 Web 服务的支持,包括: 出站 Web 服务网关 入站 Web 服务网关 Web 服务命名空间支持 出站 URI 配置 WS 消息头 MTOM 支持 您需要将此依赖项包含在项目中: dependenc

Spring 集成对 Web 服务的支持_xml

本章描述了 Spring 集成对 Web 服务的支持,包括:

  • 出站 Web 服务网关
  • 入站 Web 服务网关
  • Web 服务命名空间支持
  • 出站 URI 配置
  • WS 消息头
  • MTOM 支持

您需要将此依赖项包含在项目中:

<dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-ws</artifactId> <version>6.0.0</version></dependency>

出站 Web 服务网关

要在向通道发送消息时调用 Web 服务,您有两个选项,这两个选项都基于 Spring Web 服务项目构建:和 。 前者接受 或 作为消息有效负载。 后者支持 and 接口的任何实现。 两者都需要一个Spring Web服务,以确定要调用的Web服务的URI。 以下示例显示了用于调用 Web 服务的两个选项:​​SimpleWebServiceOutboundGateway​​​​MarshallingWebServiceOutboundGateway​​​​String​​​​javax.xml.transform.Source​​​​Marshaller​​​​Unmarshaller​​​​DestinationProvider​​

simpleGateway = new SimpleWebServiceOutboundGateway(destinationProvider); marshallingGateway = new MarshallingWebServiceOutboundGateway(destinationProvider, marshaller);

使用命名空间支持(稍后介绍​)时,只需设置 URI。 在内部,分析器配置固定的 URI 实现。 但是,如果需要在运行时动态解析 URI,则可以提供从注册表中查找 URI 等行为。 有关此策略的更多信息,请参阅 Spring Web Services DestinationProvider​ Javadoc。​​DestinationProvider​​​​DestinationProvider​​

从版本 5.0 开始,您可以为 和 提供一个外部实例,您可以为任何自定义属性配置该实例,包括(允许应用程序处理不符合标准的服务)。​​SimpleWebServiceOutboundGateway​​​​MarshallingWebServiceOutboundGateway​​​​WebServiceTemplate​​​​checkConnectionForFault​​

有关内部工作的更多详细信息,请参阅 Spring Web 服务参考指南中介绍客户端访问的章节和涵盖对象/XML 映射的章节。

入站 Web 服务网关

要在收到 Web 服务调用时向通道发送消息,您还有两个选项:和 。 前者从中提取 并将其设置为消息有效负载。 后者支持 和 接口的实现。 如果传入的 Web 服务消息是 SOAP 消息,则 SOAP 操作标头将添加到转发到请求通道的标头中。 以下示例显示了这两个选项:​​SimpleWebServiceInboundGateway​​​​MarshallingWebServiceInboundGateway​​​​javax.xml.transform.Source​​​​WebServiceMessage​​​​Marshaller​​​​Unmarshaller​​​​Message​​

simpleGateway = new SimpleWebServiceInboundGateway(); simpleGateway.setRequestChannel(forwardOntoThisChannel); simpleGateway.setReplyChannel(listenForResponseHere); //Optional marshallingGateway = new MarshallingWebServiceInboundGateway(marshaller); //set request and optionally reply channel

这两个网关都实现了Spring Web服务接口,因此可以根据标准的Spring Web服务配置来配置它们。​​MessageEndpoint​​​​MessageDispatcherServlet​​

有关如何使用这些组件的更多详细信息,请参阅 Spring Web 服务参考指南中涉及创建 Web 服务的章节。 涵盖对象/XML 映射的章节同样适用。

要将 和 配置添加到 Spring WS 基础结构中,您应该在 和 目标实现之间添加定义,就像对普通 Spring WS 应用程序所做的那样。 为此(从 Spring 集成的角度来看),Spring WS 提供了以下方便的实现:​​SimpleWebServiceInboundGateway​​​​MarshallingWebServiceInboundGateway​​​​EndpointMapping​​​​MessageDispatcherServlet​​​​MessageEndpoint​​​​EndpointMapping​​

  • ​​o.s.ws.server.endpoint.mapping.UriEndpointMapping​​
  • ​​o.s.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping​​
  • ​​o.s.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping​​
  • ​​o.s.ws.server.endpoint.mapping.XPathPayloadEndpointMapping​​

您必须在应用程序上下文中为这些类指定 bean,并根据 WS 映射算法引用 and/或 Bean 定义。​​SimpleWebServiceInboundGateway​​​​MarshallingWebServiceInboundGateway​​

有关详细信息,请参阅终结点映射。

Web 服务命名空间支持

若要配置出站 Web 服务网关,请使用命名空间中的元素,如以下示例所示:​​outbound-gateway​​​​ws​​

<int-ws:outbound-gateway id="simpleGateway" request-channel="inputChannel" uri="https://example.org"/>

此示例不提供“回复通道”。 如果 Web 服务返回非空响应,则包含该响应的响应将发送到请求消息标头中定义的回复通道。 如果不可用,则会引发通道解析异常。 如果要将回复发送到另一个通道,请在“出站网关”元素上提供“回复通道”属性。​​Message​​​​REPLY_CHANNEL​​

默认情况下,当您调用在对请求使用 String 有效负载后返回空响应的 Web 服务时,不会发送任何回复。 因此,您无需在请求中设置“回复通道”或标头。 如果您确实希望以 的形式接收空响应,则可以将“忽略空响应”属性设置为 。 这样做仅适用于对象,因为使用 a 或 对象会导致空响应,因此永远不会生成回复。​​Message​​​​Message​​​​REPLY_CHANNEL​​​​Message​​​​Message​​​​false​​​​String​​​​Source​​​​Document​​​​Message​​

若要设置入站 Web 服务网关,请使用该元素,如以下示例所示:​​inbound-gateway​​

<int-ws:inbound-gateway id="simpleGateway" request-channel="inputChannel"/>

要使用 Spring OXM 编组器或解组器,必须提供 bean 引用。 以下示例演示如何为出站编组网关提供 Bean 引用:

<int-ws:outbound-gateway id="marshallingGateway" request-channel="requestChannel" uri="https://example.org" marshaller="someMarshaller" unmarshaller="someUnmarshaller"/>

以下示例演示如何为入站编组网关提供 Bean 引用:

<int-ws:inbound-gateway id="marshallingGateway" request-channel="requestChannel" marshaller="someMarshaller" unmarshaller="someUnmarshaller"/>

大多数实现也实现了接口。 当使用这样的 时,只有属性是必需的。 即使在使用 时,您也可以为出站网关上的 提供参考。​​Marshaller​​​​Unmarshaller​​​​Marshaller​​​​marshaller​​​​Marshaller​​​​request-callback​​

对于任一出站网关类型,您可以指定属性而不是 (恰好需要其中一个)。 然后,您可以引用任何 Spring Web 服务实现(例如,在运行时从注册表中查找 URI)。​​destination-provider​​​​uri​​​​DestinationProvider​​

对于任一出站网关类型,还可以使用对任何 Spring Web 服务实现的引用来配置该属性。​​message-factory​​​​WebServiceMessageFactory​​

对于简单入站网关类型,您可以将属性设置为 将整个(而不仅仅是其有效负载)作为 转发到请求通道。 这样做可能很有用,例如,当自定义转换器直接针对​​extract-payload​​​​false​​​​WebServiceMessage​​​​Message​​​​WebServiceMessage​​

从版本 5.0 开始,引用属性允许您注入任何可能的自定义属性。​​web-service-template​​​​WebServiceTemplate​​

Web Service Java DSL 支持

以下代码片段显示了 Web 服务命名空间支持中显示的网关的等效配置:

@BeanIntegrationFlow inbound() { return IntegrationFlow.from(Ws.simpleInboundGateway() .id("simpleGateway")) ... .get();}@BeanIntegrationFlow outboundMarshalled() { return f -> f.handle(Ws.marshallingOutboundGateway() .id("marshallingGateway") .marshaller(someMarshaller()) .unmarshaller(someUnmarshalller())) ...}@BeanIntegrationFlow inboundMarshalled() { return IntegrationFlow.from(Ws.marshallingInboundGateway() .marshaller(someMarshaller()) .unmarshaller(someUnmarshalller()) .id("marshallingGateway")) ... .get();}

可以在终结点规范上以流畅的方式设置其他属性(属性取决于是否为出站网关提供了外部)。 例子:​​WebServiceTemplate​​

.from(Ws.simpleInboundGateway() .extractPayload(false)).handle(Ws.simpleOutboundGateway(template) .uri(uri) .sourceExtractor(sourceExtractor) .encodingMode(DefaultUriBuilderFactory.EncodingMode.NONE) .headerMapper(headerMapper) .ignoreEmptyResponses(true) .requestCallback(requestCallback) .uriVariableExpressions(uriVariableExpressions) .extractPayload(false))).handle(Ws.marshallingOutboundGateway() .destinationProvider(destinationProvider) .marshaller(marshaller) .unmarshaller(unmarshaller) .messageFactory(messageFactory) .encodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY) .faultMessageResolver(faultMessageResolver) .headerMapper(headerMapper) .ignoreEmptyResponses(true) .interceptors(interceptor) .messageSenders(messageSender) .requestCallback(requestCallback) .uriVariableExpressions(uriVariableExpressions)).handle(Ws.marshallingOutboundGateway(template) .uri(uri) .encodingMode(DefaultUriBuilderFactory.EncodingMode.URI_COMPONENT) .headerMapper(headerMapper) .ignoreEmptyResponses(true) .requestCallback(requestCallback) .uriVariableExpressions(uriVariableExpressions)))

出站 URI 配置

对于 Spring Web 服务支持的所有 URI 方案(参见 URI 和传输),提供了替换。 下面的示例演示如何定义它:​​<uri-variable/>​​

<ws:outbound-gateway id="gateway" request-channel="input" uri="https://springsource.org/{thing1}-{thing2}"> <ws:uri-variable name="thing1" expression="payload.substring(1,7)"/> <ws:uri-variable name="thing2" expression="headers.x"/></ws:outbound-gateway><ws:outbound-gateway request-channel="inputJms" uri="jms:{destination}?deliveryMode={deliveryMode}&priority={priority}" message-sender="jmsMessageSender"> <ws:uri-variable name="destination" expression="headers.jmsQueue"/> <ws:uri-variable name="deliveryMode" expression="headers.deliveryMode"/> <ws:uri-variable name="priority" expression="headers.jms_priority"/></ws:outbound-gateway>

如果提供 ,则不支持变量替换,并且如果提供变量,则会发生配置错误。​​DestinationProvider​​

控制 URI 编码

默认情况下,在发送请求之前,URL 字符串被编码(请参阅 UriComponentsBuilder)到 URI 对象。 在某些具有非标准 URI 的情况下,不希望执行编码。 该元素提供一个属性。 要禁用对 URL 进行编码,请将此属性设置为 (默认情况下为 )。 如果要对某些 URL 进行部分编码,可以使用 in in 来执行此操作,如以下示例所示:​​<ws:outbound-gateway/>​​​​encoding-mode​​​​NONE​​​​TEMPLATE_AND_VALUES​​​​expression​​​​<uri-variable/>​​

<ws:outbound-gateway url="https://somehost/%2f/fooApps?bar={param}" encoding-mode="NONE"> <http:uri-variable name="param" expression="T(org.apache.commons.httpclient.util.URIUtil) .encodeWithinQuery('Hello World!')"/></ws:outbound-gateway>

如果设置 ,则忽略。​​DestinationProvider​​​​encoding-mode​​

WS 消息头

Spring 集成 Web 服务网关会自动映射 SOAP 操作标头。 默认情况下,它通过使用 DefaultSoapHeaderMapper 复制到 Spring Integration 和从 Spring Integration 复制。​​MessageHeaders​​

您可以传入自己的特定于 SOAP 的标头映射程序的实现,因为网关具有支持这样做的属性。

除非由 的 或 属性显式指定,否则不会将任何用户定义的 SOAP 标头复制到 SOAP 消息或从 SOAP 消息复制。​​requestHeaderNames​​​​replyHeaderNames​​​​DefaultSoapHeaderMapper​​

使用 XML 命名空间进行配置时,可以使用 and 属性设置这些属性,也可以通过设置属性来提供自定义映射器。​​mapped-request-headers​​​​mapped-reply-headers​​​​header-mapper​​

映射用户定义的标头时,这些值还可以包含简单的通配符模式(例如 或 )。 例如,如果需要复制所有用户定义的标头,则可以使用通配符:。​​myheader*​​​​myheader​​

从版本 4.1 开始,(超类)允许为 和 属性(除了现有和)配置令牌,以映射所有用户定义的标头。​​AbstractHeaderMapper​​​​DefaultSoapHeaderMapper​​​​NON_STANDARD_HEADERS​​​​requestHeaderNames​​​​replyHeaderNames​​​​STANDARD_REQUEST_HEADERS​​​​STANDARD_REPLY_HEADERS​​

我们建议使用以下组合,而不是使用通配符 (): 这样做可避免将标头映射到回复。​​*​​​​STANDARD_REPLY_HEADERS, NON_STANDARD_HEADERS​​​​request​​

从版本 4.3 开始,您可以通过在标头映射前面加上 来否定标头映射中的模式。 否定模式获得优先级,因此诸如 not 映射 、 或 的列表。 它确实映射了标准标头、 和 。 (请注意,这包含在非否定形式和否定形式中。 因为否定值优先,所以不会映射。​​!​​​​STANDARD_REQUEST_HEADERS,thing1,thing*,!thing2,!thing3,qux,!thing1​​​​thing1​​​​thing2​​​​thing3​​​​thing4​​​​qux​​​​thing1​​​​thing1​​

如果您有一个用户定义的标头,该标头以您希望映射的标头开头,则可以使用 对其进行转义,如下所示:。 然后映射 A。​​!​​​​\​​​​STANDARD_REQUEST_HEADERS,\!myBangHeader​​​​!myBangHeader​​

入站 SOAP 标头(入站网关的请求标头和出站网关的回复标头)将映射为对象。 您可以通过访问以下内容来浏览内容:​​SoapHeaderElement​​​​Source​​

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <auth> <username>user</username> <password>pass</password> </auth> <bar>BAR</bar> <baz>BAZ</baz> <qux>qux</qux> </soapenv:Header> <soapenv:Body> ... </soapenv:Body></soapenv:Envelope>

如果是 ,则映射 、 和标头,但不映射。​​mapped-request-headers​​​​auth, ca*​​​​auth​​​​cat​​​​can​​​​qux​​

下面的示例演示如何从名为 的标头获取命名的值:​​user​​​​auth​​

...SoapHeaderElement header = (SoapHeaderElement) headers.get("auth");DOMSource source = (DOMSource) header.getSource();NodeList nodeList = source.getNode().getChildNodes();assertEquals("username", nodeList.item(0).getNodeName());assertEquals("user", nodeList.item(0).getFirstChild().getNodeValue());...

从版本 5.0 开始,支持 类型的用户定义标头,并将它们填充为 . 以下示例演示如何执行此操作:​​DefaultSoapHeaderMapper​​​​javax.xml.transform.Source​​​​<soapenv:Header>​​

Map<String, Object> headers = new HashMap<>();String authXml = "<auth xmlns='http://test.auth.org'>" + "<username>user</username>" + "<password>pass</password>" + "</auth>";headers.put("auth", new StringSource(authXml));...DefaultSoapHeaderMapper mapper = new DefaultSoapHeaderMapper();mapper.setRequestHeaderNames("auth");

上述示例的结果是以下 SOAP 信封:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <auth xmlns="http://test.auth.org"> <username>user</username> <password>pass</password> </auth> </soapenv:Header> <soapenv:Body> ... </soapenv:Body></soapenv:Envelope>

MTOM 支持

封送入站和出站 Web 服务网关通过封送器的内置功能直接支持附件(例如,提供选项)。 从版本 5.0 开始,简单的 Web 服务网关可以直接使用入站和出站实例进行操作,这些实例具有用于操作附件的 API。 当您需要发送带有附件的 Web 服务消息(来自服务器的回复或客户端请求)时,您应该直接使用 并将带有附件的 a 作为 发送到网关的请求或回复通道。 以下示例演示如何执行此操作:​​Jaxb2Marshaller​​​​mtomEnabled​​​​MimeMessage​​​​WebServiceMessageFactory​​​​WebServiceMessage​​​​payload​​

WebServiceMessageFactory messageFactory = new SaajSoapMessageFactory(MessageFactory.newInstance());MimeMessage webServiceMessage = (MimeMessage) messageFactory.createWebServiceMessage();String request = "<test>foo</test>";TransformerFactory transformerFactory = TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();transformer.transform(new StringSource(request), webServiceMessage.getPayloadResult());webServiceMessage.addAttachment("myAttachment", new ByteArrayResource("my_data".getBytes()), "plain/text");this.webServiceChannel.send(new GenericMessage<>(webServiceMessage));
上一篇:Spring Integration 的Zookeeper 支持
下一篇:没有了
网友评论