HTTP サポート

Spring Integration の HTTP サポートにより、HTTP リクエストの実行と受信 HTTP リクエストの処理が可能になります。HTTP サポートは、次のゲートウェイ実装で構成されています: HttpInboundEndpoint および HttpRequestExecutingMessageHandlerWebFlux サポートも参照してください。

この依存関係をプロジェクトに含める必要があります。

Maven
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-http</artifactId>
    <version>5.5.8</version>
</dependency>
Gradle
compile "org.springframework.integration:spring-integration-http:5.5.8"

javax.servlet:javax.servlet-api 依存関係は、ターゲットサーブレットコンテナーで提供する必要があります。

HTTP 受信コンポーネント

HTTP 経由でメッセージを受信するには、HTTP 受信チャネルアダプターまたは HTTP 受信ゲートウェイを使用する必要があります。HTTP 受信アダプターをサポートするには、Apache Tomcat (英語) Jetty (英語) などのサーブレットコンテナー内にデプロイする必要があります。これを行う最も簡単な方法は、web.xml ファイルで次のサーブレット定義を提供することにより、Spring の HttpRequestHandlerServlet (Javadoc) を使用することです。

<servlet>
    <servlet-name>inboundGateway</servlet-name>
    <servlet-class>o.s.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>

サーブレット名が Bean 名と一致することに注意してください。HttpRequestHandlerServlet の使用の詳細については、Spring Framework リファレンスドキュメントの一部である Spring を使用したリモートおよび Web サービスを参照してください。

Spring MVC アプリケーション内で実行している場合、前述の明示的なサーブレット定義は必要ありません。その場合、Spring MVC コントローラー Bean の場合と同様に、ゲートウェイの Bean 名を URL パスと照合できます。詳細については、Spring Framework リファレンスドキュメントの一部である Web MVC フレームワークを参照してください。

サンプルアプリケーションと対応する構成については、Spring Integration サンプル [GitHub] (英語) リポジトリを参照してください。Spring Integration の HTTP サポートを示す HTTP サンプル [GitHub] (英語) アプリケーションが含まれています。

次の例 Bean は、HTTP 受信エンドポイントを定義します。

<bean id="httpInbound"
  class="org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway">
  <property name="requestChannel" ref="httpRequestChannel" />
  <property name="replyChannel" ref="httpReplyChannel" />
</bean>

HttpRequestHandlingMessagingGateway は HttpMessageConverter インスタンスのリストを受け入れるか、デフォルトリストに依存します。コンバーターを使用すると、HttpServletRequest から Message へのマッピングをカスタマイズできます。デフォルトのコンバーターは、コンテンツ型が text で始まる POST リクエストに対して String メッセージを作成する単純な戦略をカプセル化します。詳細については、Javadoc を参照してください。追加のフラグ(mergeWithDefaultConverters)をカスタム HttpMessageConverter のリストとともに設定して、カスタムコンバーターの後にデフォルトコンバーターを追加できます。デフォルトでは、このフラグは false に設定されています。これは、カスタムコンバーターがデフォルトリストを置き換えることを意味します。

メッセージ変換プロセスは、(オプションの) requestPayloadType プロパティと受信 Content-Type ヘッダーを使用します。バージョン 4.3 以降、リクエストにコンテンツ型ヘッダーがない場合、RFC 2616 で推奨されているように、application/octet-stream が想定されます。以前は、このようなメッセージの本文は無視されていました。

Spring Integration 2.0 はマルチパートファイルのサポートを実装しました。リクエストが MultipartHttpServletRequest としてラップされている場合、デフォルトのコンバーターを使用すると、そのリクエストは、個々のパートのコンテンツ型に応じて、バイト配列、文字列、Spring の MultipartFile のインスタンスである値を含む MultiValueMap である Message ペイロードに変換されます。

HTTP 受信エンドポイントは、Bean の名前が multipartResolver (Spring の DispatcherServlet が期待する名前)の場合、コンテキスト内で MultipartResolver を見つけます。その Bean が見つかると、受信リクエストマッパーでマルチパートファイルのサポートが有効になります。そうでない場合、マルチパートファイルリクエストを Spring Integration Message にマップしようとすると失敗します。MultipartResolver に対する Spring のサポートの詳細については、Spring リファレンスマニュアルを参照してください。

multipart/form-data を別のサーバーにプロキシする場合は、それを生の形式のままにしておくことをお勧めします。この状況を処理するには、multipartResolver Bean をコンテキストに追加しないでください。byte[] リクエストを予期するようにエンドポイントを構成し、ByteArrayHttpMessageConverter を含むようにメッセージコンバーターをカスタマイズし、デフォルトのマルチパートコンバーターを無効にします。返信には他のコンバーターが必要になる場合があります。次の例は、このような配置を示しています。

<int-http:inbound-gateway
                  channel="receiveChannel"
                  path="/inboundAdapter.htm"
                  request-payload-type="byte[]"
                  message-converters="converters"
                  merge-with-default-converters="false"
                  supported-methods="POST" />

<util:list id="converters">
    <beans:bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
    <beans:bean class="org.springframework.http.converter.StringHttpMessageConverter" />
    <beans:bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</util:list>

クライアントにレスポンスを送信する場合、ゲートウェイの動作をカスタマイズする方法はいくつかあります。デフォルトでは、ゲートウェイは 200 ステータスコードを返送することにより、リクエストが受信されたことを確認します。Spring MVC ViewResolver によって解決される "viewName" を提供することにより、このレスポンスをカスタマイズすることができます。ゲートウェイが Message へのレスポンスを期待する必要がある場合は、expectReply フラグ (コンストラクター引数) を設定して、HTTP レスポンスを作成する前にゲートウェイが Message のレスポンスを待機するようにすることができます。次の例では、ビュー名を持つ Spring MVC コントローラーとして機能するようにゲートウェイを構成しています。

<bean id="httpInbound"
  class="org.springframework.integration.http.inbound.HttpRequestHandlingController">
  <constructor-arg value="true" /> <!-- indicates that a reply is expected -->
  <property name="requestChannel" ref="httpRequestChannel" />
  <property name="replyChannel" ref="httpReplyChannel" />
  <property name="viewName" value="jsonView" />
  <property name="supportedMethodNames" >
    <list>
      <value>GET</value>
      <value>DELETE</value>
    </list>
  </property>
</bean>

true の constructor-arg 値のため、応答を待機します。上記の例は、ゲートウェイで受け入れられる HTTP メソッド(デフォルトでは POST および GET)をカスタマイズする方法も示しています。

応答メッセージはモデルマップで利用できます。デフォルトでは、そのマップエントリのキーは "reply" ですが、エンドポイントの構成で "replyKey" プロパティを設定することにより、このデフォルトをオーバーライドできます。

ペイロード検証

バージョン 5.2 以降、HTTP 受信エンドポイントに Validator を提供して、チャネルに送信する前にペイロードをチェックできます。このペイロードは、貴重なデータに関して検証範囲を狭めるために payloadExpression 後に変換および抽出された結果です。検証失敗の処理は、Spring MVC エラー処理にあるものと完全に同じです。

HTTP 送信コンポーネント

このセクションでは、Spring Integration の HTTP 送信コンポーネントについて説明します。

HttpRequestExecutingMessageHandler を使用する

HttpRequestExecutingMessageHandler を構成するには、次のような Bean 定義を作成します。

<bean id="httpOutbound"
  class="org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler">
  <constructor-arg value="http://localhost:8080/example" />
  <property name="outputChannel" ref="responseChannel" />
</bean>

この Bean 定義は、RestTemplate に委譲することにより HTTP リクエストを実行します。次に、そのテンプレートは、HttpMessageConverter インスタンスのリストに委譲して、Message ペイロードから HTTP リクエスト本文を生成します。次の例に示すように、これらのコンバーターと ClientHttpRequestFactory インスタンスを使用するように構成できます。

<bean id="httpOutbound"
  class="org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler">
  <constructor-arg value="http://localhost:8080/example" />
  <property name="outputChannel" ref="responseChannel" />
  <property name="messageConverters" ref="messageConverterList" />
  <property name="requestFactory" ref="customRequestFactory" />
</bean>

デフォルトでは、HTTP リクエストは、JDK HttpURLConnection を使用する SimpleClientHttpRequestFactory のインスタンスを使用して生成されます。Apache Commons HTTP クライアントの使用も、(前述のように) 挿入できる CommonsClientHttpRequestFactory を通じてサポートされています。

送信ゲートウェイの場合、ゲートウェイによって生成される応答メッセージには、リクエストメッセージに存在するすべてのメッセージヘッダーが含まれます。

クッキーを使用する

基本的な Cookie サポートは、送信ゲートウェイの transfer-cookies 属性によって提供されます。true に設定すると(デフォルトは false)、レスポンスでサーバーから受信した Set-Cookie ヘッダーは、レスポンスメッセージで Cookie に変換されます。このヘッダーは、その後の送信で使用されます。これにより、次のような単純なステートフルな対話が可能になります。

…​→logonGateway→…​→doWorkGateway→…​→logoffGateway→…​

transfer-cookies が false の場合、受信した Set-Cookie ヘッダーは応答メッセージ内で Set-Cookie のままであり、後続の送信でドロップされます。

空のレスポンスボディ

HTTP はリクエスト / レスポンスプロトコルです。ただし、レスポンスには本文がなく、ヘッダーのみが含まれる場合があります。この場合、HttpRequestExecutingMessageHandler は、提供された expected-response-type に関係なく、ペイロードが org.springframework.http.ResponseEntity であるレスポンス Message を生成します。HTTP RFC ステータスコードの定義 [W3C] (英語) によると、レスポンスにメッセージ本文を含めてはならないことを義務付ける多くのステータスがあります(たとえば、204 No Content)。同じ URL を呼び出すと、レスポンス本文が返される場合と返されない場合があります。例: HTTP リソースへの最初のリクエストはコンテンツを返しますが、2 番目のリクエストはコンテンツを返しません(304 Not Modified を返します)。ただし、すべての場合において、http_statusCode メッセージヘッダーが入力されます。これは、HTTP 送信ゲートウェイの後の一部のルーティングロジックで使用できます。`<payload-type-router/>` を使用して、ResponseEntity を含むメッセージを、本文を使用したレスポンスに使用されるフローとは異なるフローにルーティングすることもできます。

expected-response-type

空のレスポンス本文に関する前述の注意に加えて、レスポンスに本文が含まれている場合、適切な expected-response-type 属性を指定するか、本文のない ResponseEntity を受け取る必要があります。expected-response-type は、レスポンス内の(設定済みまたはデフォルトの) HttpMessageConverter インスタンスおよび Content-Type ヘッダーと互換性がある必要があります。これは、抽象クラスまたはインターフェース(Java 直列化と Content-Type: application/x-java-serialized-object を使用する場合の java.io.Serializable など)でさえあります。

バージョン 5.5 以降、HttpRequestExecutingMessageHandler は extractResponseBody フラグ(デフォルトでは true)を公開して、レスポンス本文のみを返すか、提供された expectedResponseType とは関係なく、ResponseEntity 全体をレスポンスメッセージペイロードとして返します。ボディが ResponseEntity に存在しない場合、このフラグは無視され、ResponseEntity 全体が返されます。

HTTP 名前空間のサポート

Spring Integration は、http 名前空間と対応するスキーマ定義を提供します。構成に含めるには、アプリケーションコンテキスト構成ファイルで次の名前空間宣言を指定します。

<?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-http="http://www.springframework.org/schema/integration/http"
  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/http
    https://www.springframework.org/schema/integration/http/spring-integration-http.xsd">
    ...
</beans>

受信

XML 名前空間は、HTTP 受信リクエストを処理するための 2 つのコンポーネント、inbound-channel-adapter および inbound-gateway を提供します。専用のレスポンスを返さずにリクエストを処理するには、inbound-channel-adapter を使用します。次の例は、設定方法を示しています。

<int-http:inbound-channel-adapter id="httpChannelAdapter" channel="requests"
    supported-methods="PUT, DELETE"/>

レスポンスを期待するリクエストを処理するには、inbound-gateway を使用します。次の例は、設定方法を示しています。

<int-http:inbound-gateway id="inboundGateway"
    request-channel="requests"
    reply-channel="responses"/>

リクエストマッピングのサポート

Spring Integration 3.0 は、IntegrationRequestMappingHandlerMapping (Javadoc) を導入することで REST サポートを改善しました。この実装は、Spring Framework 3.1 以降で提供される拡張 REST サポートに依存しています。

HTTP 受信・ゲートウェイまたは HTTP 受信・チャネルアダプターの構文解析により、型 IntegrationRequestMappingHandlerMapping (Javadoc) の integrationRequestMappingHandlerMapping Bean が登録されます (まだ登録されていない場合)。HandlerMapping (Javadoc) のこの特定の実装は、そのロジックを RequestMappingInfoHandlerMapping (Javadoc) に委譲します。この実装は、Spring MVC の org.springframework.web.bind.annotation.RequestMapping (Javadoc) アノテーションと同様の機能を提供します。

詳しくは、@RequestMapping を使用したリクエストのマッピングを参照してください。

この目的のために、Spring Integration 3.0 は <request-mapping> 要素を導入します。このオプションの要素を <http:inbound-channel-adapter> および <http:inbound-gateway> に追加できます。path および supported-methods 属性と連動します。次の例は、受信ゲートウェイでそれを構成する方法を示しています。

<inbound-gateway id="inboundController"
    request-channel="requests"
    reply-channel="responses"
    path="/foo/{fooId}"
    supported-methods="GET"
    view-name="foo"
    error-code="oops">
   <request-mapping headers="User-Agent"
     params="myParam=myValue"
     consumes="application/json"
     produces="!text/plain"/>
</inbound-gateway>

前述の構成に基づいて、名前空間パーサーは IntegrationRequestMappingHandlerMapping (存在しない場合) のインスタンスと HttpRequestHandlingController Bean のインスタンスを作成し、それに RequestMapping (Javadoc) のインスタンスを関連付けます。この RequestMapping インスタンスは、次に Spring MVC RequestMappingInfo (Javadoc) に変換されます。

<request-mapping> 要素は、次の属性を提供します。

  • headers

  • params

  • consumes

  • produces

<http:inbound-channel-adapter> または <http:inbound-gateway> の path および supported-methods 属性を使用すると、<request-mapping> 属性は、Spring MVC の org.springframework.web.bind.annotation.RequestMapping アノテーションによって提供されるそれぞれのオプションに直接変換されます。

<request-mapping> 要素を使用すると、複数の Spring Integration HTTP 受信エンドポイントを同じ path (または同じ supported-methods)に構成でき、受信 HTTP リクエストに基づいて異なるダウンストリームメッセージフローを提供できます。

または、1 つの HTTP 受信エンドポイントのみを宣言し、Spring Integration フロー内でルーティングおよびフィルタリングロジックを適用して同じ結果を得ることができます。これにより、できるだけ早く Message をフローに取り込むことができます。次の例は、その方法を示しています。

<int-http:inbound-gateway request-channel="httpMethodRouter"
    supported-methods="GET,DELETE"
    path="/process/{entId}"
    payload-expression="#pathVariables.entId"/>

<int:router input-channel="httpMethodRouter" expression="headers.http_requestMethod">
    <int:mapping value="GET" channel="in1"/>
    <int:mapping value="DELETE" channel="in2"/>
</int:router>

<int:service-activator input-channel="in1" ref="service" method="getEntity"/>

<int:service-activator input-channel="in2" ref="service" method="delete"/>

ハンドラーマッピングの詳細については、Spring Framework Web サーブレットドキュメントまたは Spring Framework Web リアクティブドキュメントを参照してください。

IntegrationRequestMappingHandlerMapping は Spring MVC RequestMappingHandlerMapping クラスを継承し、そのロジックのほとんど、特に handleNoMatch(Set, String, HttpServletRequest) を継承し、何らかの理由でマッピングが一致しない場合に HTTP レスポンスに対して特定の 4xx エラーをスローし、アプリケーションコンテキスト内の残りのマッピングハンドラーの呼び出しを防ぎます。このため、Spring Integration と Spring MVC の両方のリクエストマッピング (たとえば、一方の POST と他方の GET ) に同じパスを設定することはサポートされていません。MVC マッピングが見つかりません ..

クロスオリジンリソースシェアリング(CORS)サポート

バージョン 4.2 以降、<http:inbound-channel-adapter> および <http:inbound-gateway> を <cross-origin> エレメントで構成できます。これは、Spring MVC の @Controller アノテーションの @CrossOrigin と同じオプションを表し、Spring Integration HTTP エンドポイントのクロスオリジンリソースシェアリング (CORS) の設定を可能にします。

  • origin: 許可された起源のリスト。* は、すべての発信元が許可されることを意味します。これらの値は、プリフライトレスポンスと実際のレスポンスの両方の Access-Control-Allow-Origin ヘッダーに配置されます。デフォルト値は * です。

  • allowed-headers: 実際のリクエスト中に使用できるリクエストヘッダーを示します。* は、クライアントによってリクエストされたすべてのヘッダーが許可されることを意味します。このプロパティは、プリフライトレスポンスの Access-Control-Allow-Headers ヘッダーの値を制御します。デフォルト値は * です。

  • exposed-headers: ユーザーエージェントがクライアントにアクセスを許可するレスポンスヘッダーのリスト。このプロパティは、実際のレスポンスの Access-Control-Expose-Headers ヘッダーの値を制御します。

  • method: 許可する HTTP リクエストメソッド: GETPOSTHEADOPTIONSPUTPATCHDELETETRACE ここで指定されたメソッドは、supported-methods のメソッドをオーバーライドします。

  • allow-credentials: ブラウザーにリクエストのドメインに関連付けられた Cookie を含める必要がある場合は true に設定し、含めない場合は false に設定します。空の文字列("")は、未定義を意味します。true の場合、プリフライトのレスポンスには Access-Control-Allow-Credentials=true ヘッダーが含まれます。デフォルト値は true です。

  • max-age: プリフライトレスポンスのキャッシュ期間を制御します。これを妥当な値に設定すると、ブラウザーが必要とするプリフライトのリクエストとレスポンスのやり取りの数を減らすことができます。このプロパティは、プリフライトレスポンスの Access-Control-Max-Age ヘッダーの値を制御します。-1 の値は未定義を意味します。デフォルト値は 1800 秒(30 分)です。

CORS Java 構成は org.springframework.integration.http.inbound.CrossOrigin クラスによって表され、そのインスタンスは HttpRequestHandlingEndpointSupport Bean に注入できます。

レスポンス状態コード

バージョン 4.1 から、<http:inbound-channel-adapter> を status-code-expression に設定して、デフォルトの 200 OK ステータスを上書きできます。式は、org.springframework.http.HttpStatus 列挙値に変換できるオブジェクトを返す必要があります。evaluationContext には BeanResolver があり、5.1 バージョン以降では、RequestEntity<?> がルートオブジェクトとして提供されています。たとえば、実行時に、ステータスコード値を返すスコープ付き Bean を解決することができます。ただし、status-code=expression="204" (コンテンツなし) や status-code-expression="T(org.springframework.http.HttpStatus).NO_CONTENT" などの固定値に設定されている場合がほとんどです。デフォルトでは、status-code-expression は null であり、通常の "200OK " レスポンス状況が戻されることを意味します。RequestEntity<?> をルートオブジェクトとして使用すると、ステータスコードは、たとえばリクエストメソッド、何らかのヘッダー、URI の内容、あるいはリクエストの本文などを条件とすることができます。次の例では、ステータスコードを ACCEPTED に設定する方法を示します。

<http:inbound-channel-adapter id="inboundController"
       channel="requests" view-name="foo" error-code="oops"
       status-code-expression="T(org.springframework.http.HttpStatus).ACCEPTED">
   <request-mapping headers="BAR"/>
</http:inbound-channel-adapter>

<http:inbound-gateway> は、レスポンス Message の http_statusCode ヘッダーから「ステータスコード」を解決します。バージョン 4.2 以降、reply-timeout 内でレスポンスが受信されない場合のデフォルトのレスポンスステータスコードは 500 Internal Server Error です。この動作を変更するには 2 つの方法があります。

  • reply-timeout-status-code-expression を追加します。これは、受信アダプターの status-code-expression と同じセマンティクスを持ちます。

  • 次の例に示すように、error-channel を追加し、HTTP ステータスコードヘッダーを含む適切なメッセージを返します。

    <int:chain input-channel="errors">
        <int:header-enricher>
            <int:header name="http_statusCode" value="504" />
        </int:header-enricher>
        <int:transformer expression="payload.failedMessage" />
    </int:chain>

ErrorMessage のペイロードは MessageTimeoutException です。String など、ゲートウェイで変換できるものに変換する必要があります。適切な候補は、例外のメッセージプロパティです。これは、expression テクニックを使用するときに使用される値です。

メインフローのタイムアウト後にエラーフローがタイムアウトした場合、500 Internal Server Error が返されるか、reply-timeout-status-code-expression が存在する場合は評価されます。

以前は、タイムアウトのデフォルトのステータスコードは 200 OK でした。その動作を復元するには、reply-timeout-status-code-expression="200" を設定します。

また、バージョン 5.4 以降、リクエストメッセージの準備中に発生したエラーがエラーチャネルに送信されます(提供されている場合)。適切な例外をスローすることについての決定は、例外を調べることによってエラーフローで行う必要があります。以前は、例外がスローされるだけで HTTP 500 サーバーのエラーレスポンスステータスが発生していましたが、場合によっては、リクエストパラメーターが正しくないことが原因で問題が発生する可能性があるため、代わりに 4xx クライアントエラーステータスの ResponseStatusException をスローする必要があります。詳細については、ResponseStatusException を参照してください。このエラーチャネルに送信された ErrorMessage には、分析用のペイロードとして元の例外が含まれています。==== URI テンプレートの変数と式

path 属性を payload-expression 属性および header 要素と組み合わせて使用することにより、受信リクエストデータをマッピングするための高度な柔軟性が得られます。

次の構成例では、次の URI を使用してリクエストを受け入れるように受信チャネルアダプターが構成されています。

/first-name/{firstName}/last-name/{lastName}

payload-expression 属性を使用する場合、{firstName} URI テンプレート変数は Message ペイロードにマップされますが、{lastName} URI テンプレート変数は lname メッセージヘッダーにマップされます。以下に例を示します。

<int-http:inbound-channel-adapter id="inboundAdapterWithExpressions"
    path="/first-name/{firstName}/last-name/{lastName}"
    channel="requests"
    payload-expression="#pathVariables.firstName">
    <int-http:header name="lname" expression="#pathVariables.lastName"/>
</int-http:inbound-channel-adapter>

URI テンプレート変数の詳細については、Spring リファレンスマニュアルの uri テンプレートパターンを参照してください。

Spring Integration 3.0 以降、ペイロードおよびヘッダー式で使用可能な既存の #pathVariables および #requestParams 変数に加えて、他の有用な式変数を追加しました。

  • #requestParamsServletRequestparameterMap からの MultiValueMap

  • #pathVariables: URI テンプレートプレースホルダーからの Map とその値。

  • #matrixVariables: Spring MVC 仕様に準じた MultiValueMap の Map#matrixVariables には Spring MVC 3.2 以降が必要であることに注意してください。

  • #requestAttributes: 現在のリクエストに関連付けられている org.springframework.web.context.request.RequestAttributes

  • #requestHeaders: 現在のリクエストからの org.springframework.http.HttpHeaders オブジェクト。

  • #cookies: 現在のリクエストからの javax.servlet.http.Cookie インスタンスの Map<String, Cookie>

メッセージフローがシングルスレッドであり、リクエストスレッド内にある場合、これらすべての値(およびその他の値)は、ThreadLocalorg.springframework.web.context.request.RequestAttributes 変数を介してダウンストリームメッセージフローの式内でアクセスできることに注意してください。次の例では、expression 属性を使用するトランスフォーマーを構成します。

<int-:transformer
    expression="T(org.springframework.web.context.request.RequestContextHolder).
                  requestAttributes.request.queryString"/>

送信

送信ゲートウェイを構成するには、ネームスペースサポートを使用できます。次のコードスニペットは、送信 HTTP ゲートウェイで使用可能な構成オプションを示しています。

<int-http:outbound-gateway id="example"
    request-channel="requests"
    url="http://localhost/test"
    http-method="POST"
    extract-request-payload="false"
    expected-response-type="java.lang.String"
    charset="UTF-8"
    request-factory="requestFactory"
    reply-timeout="1234"
    reply-channel="replies"/>

最も重要なのは、"http-method" および "expected-response-type" 属性が提供されていることに注意してください。これらは、最も一般的に設定される 2 つの値です。デフォルトの http-method は POST であり、デフォルトのレスポンス型は null です。レスポンス型が null の場合、HTTP ステータスが成功である限り、レスポンス Message のペイロードには ResponseEntity が含まれます(失敗したステータスコードは例外をスローします)。String などの別の型が必要な場合は、完全修飾クラス名(上記の例では java.lang.String)として提供します。HTTP 送信コンポーネントの空のレスポンス本文に関する注意も参照してください。

Spring Integration 2.1 以降、HTTP 送信ゲートウェイの request-timeout 属性の名前が reply-timeout に変更され、その意図がよりよく反映されました。

Spring Integration 2.2 以降、HTTP を介した Java シリアライゼーションはデフォルトで有効ではなくなりました。以前は、expected-response-type 属性を Serializable オブジェクトに設定すると、Accept ヘッダーが正しく設定されませんでした。Spring Integration 2.2 以降、SerializingHttpMessageConverter は Accept ヘッダーを application/x-java-serialized-object に設定するように更新されました。

ただし、これにより既存のアプリケーションとの非互換性が発生する可能性があるため、このコンバーターを HTTP エンドポイントに自動的に追加しないことにしました。Java 直列化を使用する場合は、message-converters 属性(XML 構成を使用する場合)または setMessageConverters() メソッド(Java 構成)を使用して、SerializingHttpMessageConverter を適切なエンドポイントに追加できます。または、代わりに JSON を使用することを検討することもできます。JSON は、クラスパスに Jackson ライブラリを含める [GitHub] (英語) ことで有効になります。

Spring Integration 2.2 以降、SpEL と http-method-expression 属性を使用して HTTP メソッドを動的に決定することもできます。この属性は http-method と相互に排他的であることに注意してください。expected-response-type の代わりに expected-response-type-expression 属性を使用して、レスポンスの型を決定する有効な SpEL 式を提供することもできます。次の構成例では expected-response-type-expression を使用しています。

<int-http:outbound-gateway id="example"
    request-channel="requests"
    url="http://localhost/test"
    http-method-expression="headers.httpMethod"
    extract-request-payload="false"
    expected-response-type-expression="payload"
    charset="UTF-8"
    request-factory="requestFactory"
    reply-timeout="1234"
    reply-channel="replies"/>

送信アダプターを単方向で使用する場合は、代わりに outbound-channel-adapter を使用できます。これは、レスポンスチャネルにメッセージを送信せずに正常なレスポンスが実行されることを意味します。レスポンスステータスコードが失敗した場合、例外をスローします。次の例に示すように、構成はゲートウェイに非常に似ています。

<int-http:outbound-channel-adapter id="example"
    url="http://localhost/example"
    http-method="GET"
    channel="requests"
    charset="UTF-8"
    extract-payload="false"
    expected-response-type="java.lang.String"
    request-factory="someRequestFactory"
    order="3"
    auto-startup="false"/>

URL を指定するには、'url' 属性または 'url-expression' 属性のいずれかを使用できます。'url' 属性は単純な文字列を取ります(以下で説明するように、URI 変数のプレースホルダーを使用)。"url-expression" は、Message をルートオブジェクトとして使用する SpEL 式であり、動的 URL を有効にします。式の評価の結果の URL には、引き続き URI 変数のプレースホルダーを含めることができます。

以前のリリースでは、一部のユーザーはプレースホルダーを使用して、URL 全体を URI 変数に置き換えていました。Spring 3.1 の変更により、"?" などのエスケープ文字に関する問題が発生する可能性があります。このため、実行時に完全に URL を生成する場合は、'url-expression' 属性を使用することをお勧めします。

URI 変数のマッピング

URL に URI 変数が含まれている場合、uri-variable 要素を使用してマップできます。この要素は、HTTP 送信ゲートウェイおよび HTTP 送信チャネルアダプターで使用できます。次の例は、zipCode URI 変数を式にマップします。

<int-http:outbound-gateway id="trafficGateway"
    url="https://local.yahooapis.com/trafficData?appid=YdnDemo&amp;zip={zipCode}"
    request-channel="trafficChannel"
    http-method="GET"
    expected-response-type="java.lang.String">
    <int-http:uri-variable name="zipCode" expression="payload.getZip()"/>
</int-http:outbound-gateway>

uri-variable 要素は、2 つの属性 name および expression を定義します。name 属性は URI 変数の名前を識別し、expression 属性は実際の値を設定するために使用されます。expression 属性を使用することにより、Spring Expression Language(SpEL)の全機能を活用できます。これにより、メッセージペイロードとメッセージヘッダーへの完全な動的アクセスが可能になります。例: 上記の構成では、getZip() メソッドが Message のペイロードオブジェクトで呼び出され、そのメソッドの結果が "zipCode" という名前の URI 変数の値として使用されます。

Spring Integration 3.0 以降、HTTP 送信エンドポイントは、評価する必要がある expression を指定する uri-variables-expression 属性をサポートし、URL テンプレート内のすべての URI 変数プレースホルダーの Map をもたらします。これは、発信メッセージに基づいて、さまざまな変数式を使用できるメカニズムを提供します。この属性は、<uri-variable/> 要素と相互に排他的です。次の例は、uri-variables-expression 属性の使用方法を示しています。

<int-http:outbound-gateway
     url="https://foo.host/{foo}/bars/{bar}"
     request-channel="trafficChannel"
     http-method="GET"
     uri-variables-expression="@uriVariablesBean.populate(payload)"
     expected-response-type="java.lang.String"/>

uriVariablesBean は次のように定義できます。

public class UriVariablesBean {
    private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();

    public Map<String, ?> populate(Object payload) {
        Map<String, Object> variables = new HashMap<String, Object>();
        if (payload instanceOf String.class)) {
            variables.put("foo", "foo"));
        }
        else {
            variables.put("foo", EXPRESSION_PARSER.parseExpression("headers.bar"));
        }
        return variables;
    }

}
uri-variables-expression は Map に評価される必要があります。Map の値は、String または Expression のインスタンスでなければなりません。この Map は、送信 Message のコンテキストでそれらの式を使用することにより、URI 変数プレースホルダーのさらなる解決のために ExpressionEvalMap に提供されます。

IMPORTANT

uriVariablesExpression プロパティは、URI 変数を評価するための非常に強力なメカニズムを提供します。前の例のように、人々は主に単純な式を使用することが予想されます。ただし、返されるマップの式が variables.put("thing1", EXPRESSION_PARSER.parseExpression(message.getHeaders().get("thing2", String.class))); である "@uriVariablesBean.populate(#root)" などの何かを構成することもできます。この式は、thing2 という名前のメッセージヘッダーで動的に提供されます。ヘッダーは信頼できないソースからのものである可能性があるため、HTTP 送信エンドポイントはこれらの式を評価するときに SimpleEvaluationContext を使用します。SimpleEvaluationContext は、SpEL 機能のサブセットのみを使用します。メッセージソースを信頼し、制限された SpEL 構造を使用する場合は、発信エンドポイントの trustedSpel プロパティを true に設定します。

URL パラメーターを作成およびエンコードするためのカスタム url-expression およびいくつかのユーティリティを使用することにより、メッセージごとに URI 変数の動的セットを提供する必要があるシナリオを実現できます。次の例は、その方法を示しています。

url-expression="T(org.springframework.web.util.UriComponentsBuilder)
                           .fromHttpUrl('https://HOST:PORT/PATH')
                           .queryParams(payload)
                           .build()
                           .toUri()"

queryParams() メソッドは引数として MultiValueMap<String, String> を想定しているため、リクエストを実行する前に、URL クエリパラメーターの実際のセットを事前に作成できます。

次の例に示すように、queryString 全体を uri-variable として提示することもできます。

<int-http:outbound-gateway id="proxyGateway" request-channel="testChannel"
              url="http://testServer/test?{queryString}">
    <int-http:uri-variable name="queryString" expression="'a=A&amp;b=B'"/>
</int-http:outbound-gateway>

この場合、URL エンコードを手動で指定する必要があります。例: この目的で org.apache.http.client.utils.URLEncodedUtils#format() を使用できます。前述のように、手動で作成された MultiValueMap<String, String> は、次の Java Streams スニペットを使用して、List<NameValuePair>format() メソッド引数に変換できます。

List<NameValuePair> nameValuePairs =
    params.entrySet()
            .stream()
            .flatMap(e -> e
                    .getValue()
                    .stream()
                    .map(v -> new BasicNameValuePair(e.getKey(), v)))
            .collect(Collectors.toList());

URI エンコードの制御

デフォルトでは、URL 文字列はリクエストを送信する前に URI オブジェクトにエンコードされます(UriComponentsBuilder (Javadoc) を参照)。非標準 URI(RabbitMQ REST API など)を使用する一部のシナリオでは、エンコードを実行することは望ましくありません。<http:outbound-gateway/> および <http:outbound-channel-adapter/> は、encoding-mode 属性を提供します。URL のエンコードを無効にするには、この属性を NONE に設定します(デフォルトでは TEMPLATE_AND_VALUES です)。一部の URL を部分的にエンコードする場合は、次の例に示すように、<uri-variable/> 内で expression を使用します。

<http: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!')"/>
</http:outbound-gateway>

Java DSL では、このオプションは BaseHttpMessageHandlerSpec.encodingMode() オプションで制御できます。同じ構成が WebFlux モジュールおよび Web サービスモジュールの同様の送信コンポーネントに適用されます。より高度なシナリオでは、外部で提供される RestTemplate で UriTemplateHandler を構成することをお勧めします。または WebFlux- WebClient の場合は UriBuilderFactory です。

Java を使用した HTTP エンドポイントの構成

次の例は、Java で受信ゲートウェイを構成する方法を示しています。

例 1: Java 構成を使用した受信ゲートウェイ
@Bean
public HttpRequestHandlingMessagingGateway inbound() {
    HttpRequestHandlingMessagingGateway gateway =
        new HttpRequestHandlingMessagingGateway(true);
    gateway.setRequestMapping(mapping());
    gateway.setRequestPayloadType(String.class);
    gateway.setRequestChannelName("httpRequest");
    return gateway;
}

@Bean
public RequestMapping mapping() {
    RequestMapping requestMapping = new RequestMapping();
    requestMapping.setPathPatterns("/foo");
    requestMapping.setMethods(HttpMethod.POST);
    return requestMapping;
}

次の例は、Java DSL で受信ゲートウェイを構成する方法を示しています。

例 2: Java DSL を使用した受信ゲートウェイ
@Bean
public IntegrationFlow inbound() {
    return IntegrationFlows.from(Http.inboundGateway("/foo")
            .requestMapping(m -> m.methods(HttpMethod.POST))
            .requestPayloadType(String.class))
        .channel("httpRequest")
        .get();
}

次の例は、Java で送信ゲートウェイを構成する方法を示しています。

例 3: Java 構成を使用した送信ゲートウェイ
@ServiceActivator(inputChannel = "httpOutRequest")
@Bean
public HttpRequestExecutingMessageHandler outbound() {
    HttpRequestExecutingMessageHandler handler =
        new HttpRequestExecutingMessageHandler("http://localhost:8080/foo");
    handler.setHttpMethod(HttpMethod.POST);
    handler.setExpectedResponseType(String.class);
    return handler;
}

次の例は、Java DSL を使用して送信ゲートウェイを構成する方法を示しています。

例 4: Java DSL を使用した送信ゲートウェイ
@Bean
public IntegrationFlow outbound() {
    return IntegrationFlows.from("httpOutRequest")
        .handle(Http.outboundGateway("http://localhost:8080/foo")
            .httpMethod(HttpMethod.POST)
            .expectedResponseType(String.class))
        .get();
}

タイムアウト処理

HTTP コンポーネントのコンテキストでは、考慮する必要がある 2 つのタイミング領域があります。

  • Spring Integration チャネルと対話するときのタイムアウト

  • リモート HTTP サーバーと対話するときのタイムアウト

コンポーネントは、タイムアウトを指定できるメッセージチャネルと対話します。例: HTTP 受信ゲートウェイは、接続された HTTP クライアントから受信したメッセージを(リクエストタイムアウトを使用する)メッセージチャネルに転送し、その結果、HTTP 受信ゲートウェイは、生成に使用されるリプライチャネル(リプライタイムアウトを使用する)からリプライメッセージを受信します。HTTP レスポンス。次の図に視覚的な説明を示します。

http inbound gateway
図 1: タイムアウト設定が HTTP 受信ゲートウェイに適用される方法

送信エンドポイントの場合、リモートサーバーとの対話中にタイミングがどのように機能するかを考慮する必要があります。次の図は、このシナリオを示しています。

http outbound gateway
図 2: HTTP 送信ゲートウェイにタイムアウト設定を適用する方法

HTTP 送信ゲートウェイまたは HTTP 送信チャネルアダプターを使用してアクティブな HTTP リクエストを行う場合、HTTP 関連のタイムアウト動作を構成することができます。これらのインスタンスでは、これら 2 つのコンポーネントは Spring の RestTemplate (Javadoc) サポートを使用して HTTP リクエストを実行します。

HTTP 送信ゲートウェイと HTTP 送信チャネルアダプターのタイムアウトを構成するには、RestTemplate Bean を直接参照するか(rest-template 属性を使用)、ClientHttpRequestFactory (Javadoc) Bean への参照を提供できます(request-factory 属性を使用)。Spring は、ClientHttpRequestFactory インターフェースの以下の実装を提供します。

request-factory 属性または rest-template 属性を明示的に構成しない場合、デフォルトの RestTemplate (SimpleClientHttpRequestFactory を使用)がインスタンス化されます。

一部の JVM 実装では、URLConnection クラスによるタイムアウトの処理に一貫性がない場合があります。

例: setConnectTimeout の Java ™ Platform、Standard エディション 6 API 仕様から:

このメソッドの一部の非標準実装は、指定されたタイムアウトを無視する場合があります。接続タイムアウトの設定を確認するには、getConnectTimeout() を呼び出してください。

特定のニーズがある場合は、タイムアウトをテストする必要があります。HttpComponentsClientHttpRequestFactory の使用を検討してください。HttpComponentsClientHttpRequestFactory は、JVM が提供する実装に依存するのではなく、Apache HttpComponents HttpClient (英語) を使用します。

Apache HttpComponents HttpClient をプーリング接続マネージャーとともに使用する場合、デフォルトでは、接続マネージャーが特定のルートごとに作成する同時接続は 2 つまで、合計で 20 までしか接続できないことに注意してください。多くの実際のアプリケーションでは、これらの制限は厳しすぎる可能性があります。この重要なコンポーネントの構成については、Apache ドキュメント (英語) を参照してください。

次の例では、接続タイムアウトと読み取りタイムアウトをそれぞれ 5 秒に設定した SimpleClientHttpRequestFactory を使用して、HTTP 送信ゲートウェイを設定します。

<int-http:outbound-gateway url="https://samples.openweathermap.org/data/2.5/weather?q={city}"
                           http-method="GET"
                           expected-response-type="java.lang.String"
                           request-factory="requestFactory"
                           request-channel="requestChannel"
                           reply-channel="replyChannel">
    <int-http:uri-variable name="city" expression="payload"/>
</int-http:outbound-gateway>

<bean id="requestFactory"
      class="org.springframework.http.client.SimpleClientHttpRequestFactory">
    <property name="connectTimeout" value="5000"/>
    <property name="readTimeout"    value="5000"/>
</bean>

HTTP 送信ゲートウェイ

HTTP 送信 ゲートウェイの場合、XML スキーマは Reply-timeout のみを定義します。応答タイムアウトは、 org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler クラスの sendTimeout プロパティにマップされます。より正確には、プロパティは拡張 AbstractReplyProducingMessageHandler クラスに設定され、最終的には MessagingTemplate にプロパティが設定されます。

sendTimeout プロパティの値はデフォルトで "-1" になり、接続された MessageChannel に適用されます。つまり、実装によっては、メッセージチャネルの送信メソッドが無期限にブロックされる場合があります。さらに、sendTimeout プロパティは、実際の MessageChannel 実装にブロッキング送信(「フル」バウンド QueueChannel など)がある場合にのみ使用されます。

HTTP 受信ゲートウェイ

HTTP 受信ゲートウェイの場合、XML スキーマは request-timeout 属性を定義します。これは、HttpRequestHandlingMessagingGateway クラス(拡張 MessagingGatewaySupport クラス)で requestTimeout プロパティを設定するために使用されます。reply-timeout 属性を使用して、同じクラスの replyTimeout プロパティにマップすることもできます。

両方のタイムアウトプロパティのデフォルトは 1000ms (1000 ミリ秒または 1 秒)です。最終的に、request-timeout プロパティは、MessagingTemplate インスタンスで sendTimeout を設定するために使用されます。一方、replyTimeout プロパティは、MessagingTemplate インスタンスで receiveTimeout プロパティを設定するために使用されます。

接続タイムアウトをシミュレートするには、10.255.255.10 などのルーティング不可能な IP アドレスに接続できます。

HTTP プロキシ構成

プロキシの背後にいて、HTTP 送信アダプターまたはゲートウェイのプロキシ設定を構成する必要がある場合、2 つのアプローチのいずれかを適用できます。ほとんどの場合、プロキシ設定を制御する標準の Java システムプロパティに依存できます。それ以外の場合は、HTTP クライアントリクエストファクトリインスタンスの Spring Bean を明示的に構成できます。

標準 Java プロキシ構成

3 つのシステムプロパティを設定して、HTTP プロトコルハンドラーで使用されるプロキシ設定を構成できます。

  • http.proxyHost: プロキシサーバーのホスト名。

  • http.proxyPort: ポート番号(デフォルトは 80 です)。

  • http.nonProxyHosts: プロキシをバイパスして、直接到達する必要があるホストのリスト。これは、| で区切られたパターンのリストです。パターンは、ワイルドカードの場合、* で開始または終了する場合があります。これらのパターンのいずれかに一致するホストには、プロキシ経由ではなく直接接続経由で到達します。

HTTPS の場合、次のプロパティを使用できます。

  • https.proxyHost: プロキシサーバーのホスト名。

  • https.proxyPort: ポート番号。デフォルト値は 80 です。

詳細については、https://docs.oracle.com/javase/jp/8/docs/technotes/guides/net/proxies.html を参照してください。

Spring の SimpleClientHttpRequestFactory

プロキシ設定をより明示的に制御する必要がある場合は、次の例に示すように、Spring の SimpleClientHttpRequestFactory を使用して「プロキシ」プロパティを設定できます。

<bean id="requestFactory"
    class="org.springframework.http.client.SimpleClientHttpRequestFactory">
    <property name="proxy">
        <bean id="proxy" class="java.net.Proxy">
            <constructor-arg>
                <util:constant static-field="java.net.Proxy.Type.HTTP"/>
            </constructor-arg>
            <constructor-arg>
                <bean class="java.net.InetSocketAddress">
                    <constructor-arg value="123.0.0.1"/>
                    <constructor-arg value="8080"/>
                </bean>
            </constructor-arg>
        </bean>
    </property>
</bean>

HTTP ヘッダーマッピング

Spring Integration は、HTTP リクエストと HTTP レスポンスの両方の HTTP ヘッダーマッピングのサポートを提供します。

デフォルトでは、すべての標準 HTTP ヘッダー [Wikipedia] (英語) は、さらに構成することなく、メッセージから HTTP リクエストまたはレスポンスヘッダーにマップされます。ただし、さらにカスタマイズが必要な場合は、ネームスペースのサポートを利用して追加の構成を提供できます。ヘッダー名のコンマ区切りリストを提供でき、ワイルドカードとして機能する "*" 文字を使用した単純なパターンを含めることができます。このような値を指定すると、デフォルトの動作が上書きされます。基本的に、その時点で完全に制御されていることを前提としています。ただし、すべての標準 HTTP ヘッダーを含める場合は、ショートカットパターン HTTP_REQUEST_HEADERS および HTTP_RESPONSE_HEADERS を使用できます。次のリストは、2 つの例を示しています(最初の例ではワイルドカードを使用しています)。

<int-http:outbound-gateway id="httpGateway"
    url="http://localhost/test2"
    mapped-request-headers="thing1, thing2"
    mapped-response-headers="X-*, HTTP_RESPONSE_HEADERS"
    channel="someChannel"/>

<int-http:outbound-channel-adapter id="httpAdapter"
    url="http://localhost/test2"
    mapped-request-headers="thing1, thing2, HTTP_REQUEST_HEADERS"
    channel="someChannel"/>

アダプターとゲートウェイは DefaultHttpHeaderMapper を使用します。DefaultHttpHeaderMapper は、適切な方向を適用できるように、受信と送信のアダプターに 2 つの静的ファクトリメソッドを提供します(HTTP リクエストとレスポンスを適切にマッピングします)。

さらにカスタマイズが必要な場合は、DefaultHttpHeaderMapper を個別に構成し、header-mapper 属性を介してアダプターに挿入することもできます。

バージョン 5.0 より前の DefaultHttpHeaderMapper は、ユーザー定義の非標準 HTTP ヘッダーのデフォルトプレフィックスは X- でした。バージョン 5.0 は、デフォルトのプレフィックスを空の文字列に変更しました。RFC-6648 [IETF] (英語) によると、このようなプレフィックスの使用は現在推奨されていません。DefaultHttpHeaderMapper.setUserDefinedHeaderPrefix() プロパティを設定することにより、引き続きこのオプションをカスタマイズできます。次の例では、HTTP ゲートウェイのヘッダーマッパーを構成します。

<int-http:outbound-gateway id="httpGateway"
    url="http://localhost/test2"
    header-mapper="headerMapper"
    channel="someChannel"/>

<bean id="headerMapper" class="o.s.i.http.support.DefaultHttpHeaderMapper">
    <property name="inboundHeaderNames" value="thing1*, *thing2, thing3"/>
    <property name="outboundHeaderNames" value="a*b, d"/>
</bean>

DefaultHttpHeaderMapper がサポートするもの以外の何かを行う必要がある場合は、HeaderMapper 戦略インターフェースを直接実装し、実装への参照を提供できます。

統合グラフコントローラー

バージョン 4.3 以降、HTTP モジュールは @EnableIntegrationGraphController 構成クラスアノテーションと <int-http:graph-controller/> XML 要素を提供して、IntegrationGraphServer を REST サービスとして公開します。詳細については、統合グラフを参照してください。

HTTP サンプル

このセクションでは、Spring Integration の HTTP サポートについてのいくつかの例を挙げて説明します。

マルチパート HTTP リクエスト — RestTemplate(クライアント)および Http 受信ゲートウェイ (サーバー)

この例は、Spring の RestTemplate でマルチパート HTTP リクエストを送信し、Spring Integration HTTP 受信アダプターで受信することがいかに簡単かを示しています。MultiValueMap を作成し、マルチパートデータを入力します。RestTemplate は、それを MultipartHttpServletRequest に変換することで残りを処理します。この特定のクライアントは、会社の名前とイメージファイル(会社のロゴ)を含むマルチパート HTTP リクエストを送信します。次のリストに例を示します。

RestTemplate template = new RestTemplate();
String uri = "http://localhost:8080/multipart-http/inboundAdapter.htm";
Resource s2logo =
   new ClassPathResource("org/springframework/samples/multipart/spring09_logo.png");
MultiValueMap map = new LinkedMultiValueMap();
map.add("company", "SpringSource");
map.add("company-logo", s2logo);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("multipart", "form-data"));
HttpEntity request = new HttpEntity(map, headers);
ResponseEntity<?> httpResponse = template.exchange(uri, HttpMethod.POST, request, null);

クライアントに必要なのはそれだけです。

サーバー側には、次の構成があります。

<int-http:inbound-channel-adapter id="httpInboundAdapter"
    channel="receiveChannel"
    path="/inboundAdapter.htm"
    supported-methods="GET, POST"/>

<int:channel id="receiveChannel"/>

<int:service-activator input-channel="receiveChannel">
    <bean class="org.springframework.integration.samples.multipart.MultipartReceiver"/>
</int:service-activator>

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

'httpInboundAdapter' はリクエストを受信し、LinkedMultiValueMap であるペイロードを持つ Message に変換します。次に、次の例に示すように、"multipartReceiver" サービスアクティベータでそれを解析します。

public void receive(LinkedMultiValueMap<String, Object> multipartRequest){
    System.out.println("### Successfully received multipart request ###");
    for (String elementName : multipartRequest.keySet()) {
        if (elementName.equals("company")){
            System.out.println("\t" + elementName + " - " +
                ((String[]) multipartRequest.getFirst("company"))[0]);
        }
        else if (elementName.equals("company-logo")){
            System.out.println("\t" + elementName + " - as UploadedMultipartFile: " +
                ((UploadedMultipartFile) multipartRequest
                    .getFirst("company-logo")).getOriginalFilename());
        }
    }
}

次の出力が表示されます。

### Successfully received multipart request ###
   company - SpringSource
   company-logo - as UploadedMultipartFile: spring09_logo.png