Http 入站组件
要通过 HTTP 接收消息,你需要使用 HTTP 入站通道适配器或 HTTP 入站网关。为了支持 HTTP 入站适配器,它们需要部署在诸如 [Apache Tomcat] 或 [Jetty] 之类的 servlet 容器中。最简单的方法是使用 Spring 的 [HttpRequestHandlerServlet],通过在 web.xml
文件中提供以下 servlet 定义:
<web-app>
<servlet>
<servlet-name>inbound-http</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>inbound-http</servlet-name>
<url-pattern>/path</url-pattern>
</servlet-mapping>
</web-app>
<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 控制器 bean 所做的那样。有关更多信息,请参阅 Web MVC 框架,这是 Spring Framework 参考文档的一部分。
对于示例应用程序和相应的配置,请参见 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 版开始,如果请求没有内容类型标头,则假定为 application/octet-stream
,这是由 RFC 2616
推荐的。以前,此类消息的正文将被忽略。
Spring Integration 2.0 实现了多部分文件支持。如果请求已被包装为 MultipartHttpServletRequest
,当您使用默认转换器时,该请求将被转换为一个 Message
负载,该负载是一个 MultiValueMap
,其中的值可能是字节数组、字符串或 Spring 的 MultipartFile
实例,具体取决于各个部分的内容类型。
如果有一个bean的名字是 multipartResolver
(这是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
状态码来回应该请求已被接收。可以通过提供一个 'viewName' 让 Spring MVC 的 ViewResolver
解析来定制此响应。如果网关应期待对 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' 属性来覆盖此默认值。
Payload 验证
从 5.2 版本开始,HTTP 入站端点可以提供一个 Validator
以在将有效负载发送到通道之前进行检查。此有效负载已经是 payloadExpression
转换和提取后的结果,以缩小针对有价值数据的验证范围。验证失败处理与我们在 Spring MVC 错误处理 中的内容完全相同。