Web サービスのサポート
この章では、Spring Integration の Web サービスのサポートについて説明します。
この依存関係をプロジェクトに含める必要があります。
送信 Web サービスゲートウェイ
チャネルにメッセージを送信するときに Web サービスを呼び出すには、2 つのオプションがあります。どちらも Spring Web Services プロジェクトに基づいて構築されています: SimpleWebServiceOutboundGateway
および MarshallingWebServiceOutboundGateway
。前者は、メッセージペイロードとして String
または javax.xml.transform.Source
を受け入れます。後者は、Marshaller
および Unmarshaller
インターフェースの実装をサポートします。どちらも、呼び出される Web サービスの URI を決定するために Spring Web Services DestinationProvider
が必要です。次の例は、Web サービスを呼び出すための両方のオプションを示しています。
simpleGateway = new SimpleWebServiceOutboundGateway(destinationProvider);
marshallingGateway = new MarshallingWebServiceOutboundGateway(destinationProvider, marshaller);
ネームスペースサポート(後述)を使用する場合、必要なのは URI のみです。内部的に、パーサーは固定 URI DestinationProvider 実装を構成します。ただし、実行時に URI の動的な解決が必要な場合は、DestinationProvider はレジストリから URI を検索するなどの動作を提供できます。この戦略の詳細については、Spring Web Services DestinationProvider (Javadoc) Javadoc を参照してください。 |
バージョン 5.0 から、SimpleWebServiceOutboundGateway
および MarshallingWebServiceOutboundGateway
に外部 WebServiceTemplate
インスタンスを提供できます。これは、checkConnectionForFault
(アプリケーションが非準拠サービスを処理できるようにする)を含むカスタムプロパティ用に設定できます。
内部の仕組みの詳細については、Spring Web Services リファレンスガイドのクライアントアクセスに関する章とオブジェクト / XML マッピングに関する章を参照してください。
受信 Web サービスゲートウェイ
Web サービス呼び出しの受信時にチャネルにメッセージを送信するには、再び 2 つのオプション SimpleWebServiceInboundGateway
と MarshallingWebServiceInboundGateway
があります。前者は、WebServiceMessage
から javax.xml.transform.Source
を抽出し、それをメッセージペイロードとして設定します。後者は、Marshaller
および Unmarshaller
インターフェースの実装をサポートします。受信 Web サービスメッセージが SOAP メッセージの場合、SOAP アクションヘッダーは、リクエストチャネルに転送される Message
のヘッダーに追加されます。次の例は、両方のオプションを示しています。
simpleGateway = new SimpleWebServiceInboundGateway();
simpleGateway.setRequestChannel(forwardOntoThisChannel);
simpleGateway.setReplyChannel(listenForResponseHere); //Optional
marshallingGateway = new MarshallingWebServiceInboundGateway(marshaller);
//set request and optionally reply channel
両方のゲートウェイは、Spring Web Services MessageEndpoint
インターフェースを実装しているため、標準 Spring Web Services 構成に従って MessageDispatcherServlet
で構成できます。
これらのコンポーネントの使用方法の詳細については、Spring Web Services リファレンスガイドの Web サービスの作成に関する章を参照してください。オブジェクト / XML マッピングをカバーする章もまた適用可能です。
SimpleWebServiceInboundGateway
および MarshallingWebServiceInboundGateway
構成を Spring WS インフラストラクチャに追加するには、通常の Spring WS アプリケーションの場合と同様に、MessageDispatcherServlet
とターゲット MessageEndpoint
実装の間に EndpointMapping
定義を追加する必要があります。この目的のために(Spring Integration の観点から)、Spring WS は次の便利な 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 マッピングアルゴリズムに従って SimpleWebServiceInboundGateway
および / または MarshallingWebServiceInboundGateway
Bean 定義を参照する必要があります。
詳細については、エンドポイントマッピングを参照してください。
Web サービス名前空間のサポート
送信 Web サービスゲートウェイを構成するには、次の例に示すように、ws
名前空間の outbound-gateway
要素を使用します。
<int-ws:outbound-gateway id="simpleGateway"
request-channel="inputChannel"
uri="https://example.org"/>
この例では、「レスポンスチャネル」は提供されません。Web サービスが空でないレスポンスを返す場合、そのレスポンスを含む Message は、リクエストメッセージの REPLY_CHANNEL ヘッダーで定義されたレスポンスチャネルに送信されます。それが利用できない場合、チャンネル解決例外がスローされます。代わりに別のチャネルにレスポンスを送信する場合は、'outbound-gateway' 要素で 'reply-channel' 属性を提供します。 |
デフォルトでは、リクエスト Message にストリングペイロードを使用した後に空のレスポンスを返す Web サービスを呼び出すと、レスポンス Message は送信されません。「返信チャネル」を設定したり、リクエスト Message に REPLY_CHANNEL ヘッダーを設定したりする必要はありません。空のレスポンスを Message として実際に受信する場合は、'ignore-empty-responses' 属性を false に設定できます。Source または Document オブジェクトを使用すると null レスポンスが発生し、その結果レスポンス Message が生成されないため、String オブジェクトに対してのみ機能します。 |
受信 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 の参照を提供することもできます。 |
どちらの送信ゲートウェイ型でも、uri
の代わりに destination-provider
属性を指定できます(正確に 1 つが必要です)。その後、Spring Web Services DestinationProvider
実装を参照できます(たとえば、実行時にレジストリから URI を検索するため)。
どちらの送信ゲートウェイ型でも、message-factory
属性は、Spring Web Services WebServiceMessageFactory
実装への参照を使用して構成できます。
単純な受信ゲートウェイ型の場合、extract-payload
属性を false
に設定して、ペイロードだけでなく Message
として WebServiceMessage
全体をリクエストチャネルに転送できます。これは、たとえば、カスタムトランスフォーマーが WebServiceMessage
に対して直接動作する場合に便利です。
バージョン 5.0 以降、web-service-template
参照属性を使用して、可能なカスタムプロパティを使用して WebServiceTemplate
を挿入できます。
Web サービス Java DSL サポート
Web サービス名前空間のサポートに示されているゲートウェイの同等の構成を以下のスニペットに示します。
@Bean
IntegrationFlow inbound() {
return IntegrationFlows.from(Ws.simpleInboundGateway()
.id("simpleGateway"))
...
.get();
}
@Bean
IntegrationFlow outboundMarshalled() {
return f -> f.handle(Ws.marshallingOutboundGateway()
.id("marshallingGateway")
.marshaller(someMarshaller())
.unmarshaller(someUnmarshalller()))
...
}
@Bean
IntegrationFlow inboundMarshalled() {
return IntegrationFlows.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 Services(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 文字列は URI オブジェクトにエンコードされます(UriComponentsBuilder
(Javadoc) を参照)。非標準の URI を使用する一部のシナリオでは、エンコードを実行することは望ましくありません。<ws:outbound-gateway/>
要素は encoding-mode
属性を提供します。URL のエンコードを無効にするには、この属性を NONE
に設定します(デフォルトでは TEMPLATE_AND_VALUES
です)。一部の URL を部分的にエンコードする場合は、次の例に示すように、<uri-variable/>
内で expression
を使用してエンコードできます。
<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 Integration Web サービスゲートウェイは、SOAP アクションヘッダーを自動的にマップします。デフォルトでは、DefaultSoapHeaderMapper
(Javadoc) を使用して Spring Integration MessageHeaders
との間でコピーされます。
ゲートウェイにはそうすることをサポートするプロパティがあるため、SOAP 固有のヘッダーマッパーの独自の実装を渡すことができます。
DefaultSoapHeaderMapper
の requestHeaderNames
または replyHeaderNames
プロパティで明示的に指定されていない限り、ユーザー定義の SOAP ヘッダーは SOAP メッセージとの間でコピーされません。
構成に XML 名前空間を使用する場合、mapped-request-headers
および mapped-reply-headers
属性を使用してこれらのプロパティを設定でき、header-mapper
属性を設定してカスタムマッパーを提供できます。
ユーザー定義ヘッダーをマッピングする場合、値に単純なワイルドカードパターン(myheader* や myheader など)を含めることもできます。例: すべてのユーザー定義ヘッダーをコピーする必要がある場合は、ワイルドカード文字 を使用できます。 |
バージョン 4.1 以降、AbstractHeaderMapper
(DefaultSoapHeaderMapper
スーパークラス)により、NON_STANDARD_HEADERS
トークンを(既存の STANDARD_REQUEST_HEADERS
および STANDARD_REPLY_HEADERS
に加えて) requestHeaderNames
および replyHeaderNames
プロパティ用に構成して、すべてのユーザー定義ヘッダーをマップできます。
ワイルドカード(* )を使用するのではなく、次の組み合わせを使用することをお勧めします: STANDARD_REPLY_HEADERS, NON_STANDARD_HEADERS 。そうすることで、request ヘッダーを応答にマッピングすることを回避できます。 |
バージョン 4.3 以降では、パターンの前に !
を付けることにより、ヘッダーマッピングのパターンを無効にすることができます。否定パターンが優先されるため、STANDARD_REQUEST_HEADERS,thing1,thing*,!thing2,!thing3,qux,!thing1
などのリストは thing1
、thing2
、thing3
をマップしません。標準ヘッダー、thing4
、qux
をマップします。(thing1
は、非否定形式と否定形式の両方に含まれていることに注意してください。否定された値が優先されるため、thing1
はマップされません。)
マッピングしたい ! で始まるユーザー定義ヘッダーがある場合は、次のように \ でエスケープできます: 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
はマップされません。
次の例は、auth
という名前のヘッダーから user
という名前の値を取得する方法を示しています。
...
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 Support
マーシャリングの受信および送信 Web サービスゲートウェイは、マーシャラーの組み込み機能を介して直接添付ファイルをサポートします(たとえば、Jaxb2Marshaller
は mtomEnabled
オプションを提供します)。バージョン 5.0 以降、単純な Web サービスゲートウェイは、添付ファイルを操作する API を備えた受信および送信 MimeMessage
インスタンスで直接動作できます。添付ファイル付きの Web サービスメッセージ(サーバーからの応答またはクライアントリクエスト)を送信する必要がある場合は、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));