Http Inbound Components

要通过 HTTP 接收消息,您需要使用 HTTP 入站通道适配器或 HTTP 入站网关。为了支持 HTTP 入站适配器,它们需要部署在 servlet 容器中,例如 Apache TomcatJetty。执行此操作最简单的方法是使用 Spring 的 HttpRequestHandlerServlet,方法是在 web.xml 文件中提供以下 servlet 定义:

To receive messages over HTTP, you need to use an HTTP inbound channel adapter or an HTTP inbound gateway. To support the HTTP inbound adapters, they need to be deployed within a servlet container such as Apache Tomcat or Jetty. The easiest way to do this is to use Spring’s HttpRequestHandlerServlet, by providing the following servlet definition in the web.xml file:

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

请注意,servlet 名称与 bean 名称相匹配。有关详细信息,请参见 `HttpRequestHandlerServlet`Javadoc。

Notice that the servlet name matches the bean name. For more information see the HttpRequestHandlerServlet Javadocs.

如果您在 Spring MVC 应用程序中运行,则无需上述显式 Servlet 定义。在这种情况下,可以将您的网关的 bean 名称与 URL 路径进行匹配,就像针对 Spring MVC 控制器 bean 所做的那样。有关更多信息,请参阅 Spring 框架参考文档一部分的 Web MVC framework

If you are running within a Spring MVC application, then the aforementioned explicit servlet definition is not necessary. In that case, the bean name for your gateway can be matched against the URL path as you would for a Spring MVC Controller bean. For more information, see Web MVC framework, which is part of the Spring Framework Reference documentation.

有关示例应用程序和相应配置,请参阅 Spring Integration Samples 存储库。它包含 HTTP sample 应用程序,展示了 Spring Integration 的 HTTP 支持。

For a sample application and the corresponding configuration, see the Spring Integration Samples repository. It contains the HTTP sample application, which demonstrates Spring Integration’s HTTP support.

以下示例 bean 定义了一个 HTTP 入站端点:

The following example bean defines an HTTP inbound endpoint:

<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,这意味着自定义转换器将替换默认列表。

The HttpRequestHandlingMessagingGateway accepts a list of HttpMessageConverter instances or else relies on a default list. The converters allow customization of the mapping from HttpServletRequest to Message. The default converters encapsulate simple strategies, which (for example) create a String message for a POST request where the content type starts with text. See the Javadoc for full details. An additional flag (mergeWithDefaultConverters) can be set along with the list of custom HttpMessageConverter to add the default converters after the custom converters. By default, this flag is set to false, meaning that the custom converters replace the default list.

消息转换过程使用(可选) requestPayloadType 属性​​和传入的 Content-Type 头。从 4.3 版本开始,如果请求没有内容类型头,则假设是 application/octet-stream,如`RFC 2616` 推荐的那样。以前,这种消息的主体被忽略。

The message conversion process uses the (optional) requestPayloadType property and the incoming Content-Type header. Starting with version 4.3, if a request has no content type header, application/octet-stream is assumed, as recommended by RFC 2616. Previously, the body of such messages was ignored.

Spring Integration 2.0 实现了多部分文件支持。如果你在使用默认转换器时将请求包装为 MultipartHttpServletRequest,则该请求将被转换为`Message` 负载,MultiValueMap`包含根据各个部分的内容类型可能为字节数组、字符串或 Spring的 `MultipartFile 实例的值。

Spring Integration 2.0 implemented multipart file support. If the request has been wrapped as a MultipartHttpServletRequest, when you use the default converters, that request is converted to a Message payload that is a MultiValueMap containing values that may be byte arrays, strings, or instances of Spring’s MultipartFile, depending on the content type of the individual parts.

如果上下文中存在`MultipartResolver`的 bean 名称是 multipartResolver (Spring 的 DispatcherServlet 预期的名称),则 HTTP 入站端点将找到该 bean。如果它找到该 bean,则启用入站请求映射器中的多部分文件支持。否则,当它尝试将多部分文件请求映射到 Spring Integration Message 时,它会失败。有关 Spring 对 MultipartResolver 的支持的更多信息,请参阅 Spring Reference Manual

The HTTP inbound endpoint locates a MultipartResolver in the context if one has a bean name of multipartResolver (the same name expected by Spring’s DispatcherServlet). If it does locate that bean, the support for multipart files is enabled on the inbound request mapper. Otherwise, it fails when it tries to map a multipart file request to a Spring Integration Message. For more on Spring’s support for MultipartResolver, see the Spring Reference Manual.

如果您希望将 multipart/form-data`代理到另一个服务器,则最好将其保留为原始形式。为了处理这种情况,不要将 `multipartResolver`bean 添加到上下文中。将端点配置为期待一个 `byte[]`请求,自定义消息转换器以包括 `ByteArrayHttpMessageConverter,并禁用默认的多部件转换器。您可能需要一些其他转换器才能回复。以下示例演示了此类安排:

If you wish to proxy a multipart/form-data to another server, it may be better to keep it in raw form. To handle this situation, do not add the multipartResolver bean to the context. Configure the endpoint to expect a byte[] request, customize the message converters to include a ByteArrayHttpMessageConverter, and disable the default multipart converter. You may need some other converters for the replies. The following example shows such an arrangement:

<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 控制器:

When you send a response to the client, you have a number of ways to customize the behavior of the gateway. By default, the gateway acknowledges that the request was received by sending a 200 status code back. It is possible to customize this response by providing a 'viewName' to be resolved by the Spring MVC ViewResolver. If the gateway should expect a reply to the Message, you can set the expectReply flag (constructor argument) to cause the gateway to wait for a reply Message before creating an HTTP response. The following example configures a gateway to serve as a Spring MVC Controller with a view name:

<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

Because of the constructor-arg value of true, it waits for a reply. The preceding example also shows how to customize the HTTP methods accepted by the gateway, which are POST and GET by default.

回复消息可在模型图中获得。默认情况下,该映射条目的键为 reply,但您可以通过设置端点配置中的 replyKey 属性来覆盖此默认值。

The reply message is available in the model map. By default, the key for that map entry is 'reply', but you can override this default by setting the 'replyKey' property on the endpoint’s configuration.

Payload Validation

从 5.2 版开始,HTTP 入站端点可以提供 `Validator`来检查负载,然后再发送到通道。此负载已经在 `payloadExpression`之后转换和提取的结果,以缩小与有价值数据有关的验证范围。验证失败处理与 Spring MVC Error Handling中的完全相同。

Starting with version 5.2, the HTTP inbound endpoints can be supplied with a Validator to check a payload before sending into the channel. This payload is already a result of conversion and extraction after payloadExpression to narrow a validation scope in regard to the valuable data. The validation failure handling is fully the same what we have in Spring MVC Error Handling.