HTTP 接收組件

若要透過 HTTP 接收訊息,您需要使用 HTTP 輸入通道適配器或 HTTP 輸入閘道。為了支援 HTTP 輸入適配器,它們需要部署在 Servlet 容器中,例如 Apache TomcatJetty。最簡單的方法是使用 Spring 的 HttpRequestHandlerServlet,方法是在 web.xml 檔案中提供以下 Servlet 定義

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

請注意,Servlet 名稱與 Bean 名稱相符。如需更多資訊,請參閱 HttpRequestHandlerServlet Javadoc。

如果您在 Spring MVC 應用程式中執行,則不需要上述明確的 Servlet 定義。在這種情況下,您可以將閘道的 Bean 名稱與 URL 路徑進行比對,就像對 Spring MVC Controller Bean 一樣。如需更多資訊,請參閱 Web MVC 框架,這是 Spring Framework 參考文件的一部分。

如需範例應用程式和相應的設定,請參閱 Spring Integration 範例 儲存庫。它包含 HTTP 範例 應用程式,示範了 Spring Integration 的 HTTP 支援。

以下範例 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 實例的列表,否則依賴預設列表。轉換器允許自訂從 HttpServletRequestMessage 的映射。預設轉換器封裝了簡單的策略,例如,針對內容類型以 text 開頭的 POST 請求建立 String 訊息。請參閱 Javadoc 以取得完整詳細資訊。可以設定一個額外的旗標 (mergeWithDefaultConverters) 以及自訂 HttpMessageConverter 的列表,以在自訂轉換器之後新增預設轉換器。預設情況下,此旗標設定為 false,表示自訂轉換器會取代預設列表。

訊息轉換過程使用 (可選) requestPayloadType 屬性和傳入的 Content-Type 標頭。從 4.3 版開始,如果請求沒有內容類型標頭,則會假設為 application/octet-stream,如 RFC 2616 所建議。先前,此類訊息的主體會被忽略。

Spring Integration 2.0 實作了 multipart 檔案支援。如果請求已包裝為 MultipartHttpServletRequest,當您使用預設轉換器時,該請求會轉換為 Message 負載,該負載是 MultiValueMap,其中包含的值可能是位元組陣列、字串或 Spring 的 MultipartFile 實例,具體取決於個別部分的內容類型。

HTTP 輸入端點會在 Context 中尋找 MultipartResolver,如果有一個 Bean 名稱為 multipartResolver (與 Spring 的 DispatcherServlet 預期的名稱相同)。如果它找到該 Bean,則會對輸入請求映射器啟用 multipart 檔案的支援。否則,當它嘗試將 multipart 檔案請求映射到 Spring Integration Message 時,它會失敗。如需 Spring 對 MultipartResolver 支援的更多資訊,請參閱 Spring 參考手冊

如果您希望將 multipart/form-data 代理到另一個伺服器,最好將其保持原始形式。若要處理這種情況,請勿將 multipartResolver Bean 新增到 Context。設定端點以預期 byte[] 請求,自訂訊息轉換器以包含 ByteArrayHttpMessageConverter,並停用預設 multipart 轉換器。您可能需要一些其他轉換器來處理回覆。以下範例顯示了這樣一種安排

<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 Controller

<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>

由於 constructor-arg 的值為 true,因此它會等待回覆。前面的範例也示範了如何自訂閘道接受的 HTTP 方法,預設為 POSTGET

回覆訊息可在模型映射中取得。預設情況下,該映射條目的索引鍵為 'reply',但您可以透過在端點的設定上設定 'replyKey' 屬性來覆寫此預設值。

負載驗證

從 5.2 版開始,可以為 HTTP 輸入端點提供 Validator,以在將負載傳送到通道之前檢查負載。此負載已經是轉換和提取的結果,在 payloadExpression 之後縮小了關於有價值資料的驗證範圍。驗證失敗處理與我們在 Spring MVC 錯誤處理 中的處理方式完全相同。