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 名称可以像 Spring MVC 控制器 bean 那样与 URL 路径匹配。有关更多信息,请参阅 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>

HttpRequestHandlerMessagingGateway 接受一个 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 实例的值,具体取决于各个部分的内容类型。

如果上下文中存在 bean 名称为 multipartResolverMultipartResolver(与 Spring 的 DispatcherServlet 期望的名称相同),则 HTTP 入站端点会定位它。如果定位到该 bean,则在入站请求映射器上启用 multipart 文件支持。否则,当尝试将 multipart 文件请求映射到 Spring Integration Message 时会失败。有关 Spring 对 MultipartResolver 的更多支持,请参阅 Spring 参考手册

如果你希望将 multipart/form-data 代理到另一个服务器,最好将其保持为原始形式。要处理这种情况,请不要将 multipartResolver bean 添加到上下文中。配置端点以期望 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 控制器:

<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 错误处理中的方式完全相同。