Http 入站组件
要通过HTTP接收消息,您需要使用HTTP入站通道适配器或HTTP入站网关。为了支持HTTP入站适配器,它们需要部署在servlet容器中,例如Apache Tomcat或Jetty。最简单的方法是使用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 的 Javadocs。
如果您在 Spring MVC 应用程序中运行,则无需进行上述显式的 Servlet 定义。在这种情况下,您的网关的 Bean 名称可以像 Spring MVC Controller Bean 一样与 URL 路径匹配。更多信息,请参阅 Web MVC 框架,这是 Spring 框架参考文档的一部分。
如需查看示例应用及其对应配置,请参阅 Spring Integration Samples 仓库。其中包含 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 实例列表,否则会依赖默认列表。这些转换器允许自定义从 HttpServletRequest 到 Message 的映射。默认转换器封装了简单的策略,例如,对于内容类型以 text 开头的 POST 请求,会创建一个 String 消息。完整详情请参阅 Javadoc。可以设置一个额外的标志 (mergeWithDefaultConverters) 以及自定义 HttpMessageConverter 列表,以便在自定义转换器之后添加默认转换器。默认情况下,此标志设置为 false,意味着自定义转换器会替换默认列表。
消息转换过程使用(可选的)requestPayloadType 属性以及传入的 Content-Type 头部。从 4.3 版本开始,如果请求没有内容类型头部,将按照 RFC 2616 的建议,假定为 application/octet-stream。在此之前,此类消息的正文会被忽略。
Spring Integration 2.0 实现了对多部分文件的支持。如果请求已被包装为 MultipartHttpServletRequest,当您使用默认转换器时,该请求会被转换为一个 Message 负载,该负载是一个 MultiValueMap,其中包含的值可能是字节数组、字符串或 Spring 的 MultipartFile 实例,具体取决于各个部分的内容类型。
如果上下文中存在名为 multipartResolver 的 bean(与 Spring DispatcherServlet 所期望的名称相同),HTTP 入站端点会定位到 MultipartResolver。如果定位到该 bean,入站请求映射器将启用对多部分文件的支持。否则,当尝试将多部分文件请求映射到 Spring Integration Message 时,操作将失败。有关 Spring 对 MultipartResolver 支持的更多信息,请参阅 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>
由于 constructor-arg 的值为 true,它会等待回复。前面的示例还展示了如何自定义网关接受的 HTTP 方法,默认情况下为 POST 和 GET。
回复消息可在模型映射中找到。默认情况下,该映射条目的键为 'reply',但您可以通过在端点配置中设置 'replyKey' 属性来覆盖此默认值。
有效负载验证
从版本5.2开始,可以为HTTP入站端点提供一个 Validator,以便在发送到通道之前检查负载。该负载已经是经过 payloadExpression 转换和提取后的结果,以缩小对有价值数据的验证范围。验证失败的处理方式与Spring MVC中的错误处理完全相同。