Spring Integration的HTTP支持
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Integration的HTTP支持相关的知识,希望对你有一定的参考价值。
Spring Integration的HTTP支持允许运行HTTP请求和处理入站HTTP请求。 HTTP 支持由以下网关实现组成:和 。 另请参阅 WebFlux 支持。HttpInboundEndpoint
HttpRequestExecutingMessageHandler
您需要将此依赖项包含在项目中:
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
<version>6.0.0</version>
</dependency>
必须在目标 Servlet 容器上提供依赖关系。jakarta.servlet:jakarta.servlet-api
Http 入站组件
要通过 HTTP 接收消息,您需要使用 HTTP 入站通道适配器或 HTTP 入站网关。 为了支持 HTTP 入站适配器,它们需要部署在 Servlet 容器(如 Apache Tomcat 或 Jetty)中。 最简单的方法是使用 Spring 的 HttpRequestHandlerServlet,通过在文件中提供以下 servlet 定义:web.xml
<servlet>
<servlet-name>inboundGateway</servlet-name>
<servlet-class>o.s.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
请注意,servlet 名称与 Bean 名称匹配。 有关使用 的更多信息,请参阅使用 Spring 的远程处理和 Web 服务,这是 Spring 框架参考文档的一部分。HttpRequestHandlerServlet
如果你在Spring MVC应用程序中运行,那么前面提到的显式servlet定义是不必要的。 在这种情况下,网关的 Bean 名称可以与 URL 路径匹配,就像 Spring MVC 控制器 Bean 一样。 有关更多信息,请参阅 Web MVC 框架,它是 Spring 框架参考文档的一部分。
有关示例应用程序和相应的配置,请参阅 Spring 集成示例存储库。 它包含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>
接受实例列表,否则依赖于默认列表。 转换器允许自定义从 到 的映射。 默认转换器封装了简单的策略,例如,这些策略为内容类型以 开头的请求创建消息。 有关完整详细信息,请参阅 Javadoc。 可以设置一个附加标志 () 以及自定义列表,以在自定义转换器之后添加默认转换器。 默认情况下,此标志设置为 ,这意味着自定义转换器将替换默认列表。HttpRequestHandlingMessagingGateway
HttpMessageConverter
HttpServletRequest
Message
String
POST
text
mergeWithDefaultConverters
HttpMessageConverter
false
消息转换过程使用 (可选) 属性和传入标头。 从版本 4.3 开始,如果请求没有内容类型标头,则假定为 ,如 所建议的那样。 以前,此类消息的正文被忽略。requestPayloadType
Content-Type
application/octet-stream
RFC 2616
Spring Integration 2.0 实现了多部分文件支持。 如果请求已包装为 ,当您使用默认转换器时,该请求将转换为有效负载,该有效负载包含的值可能是字节数组、字符串或 Spring 的实例,具体取决于各个部分的内容类型。MultipartHttpServletRequest
Message
MultiValueMap
MultipartFile
HTTP 入站端点在上下文中定位一个 bean 名称 (与 Spring 的预期名称相同)。 如果它确实找到了该 Bean,则会在入站请求映射器上启用对多部分文件的支持。 否则,当它尝试将多部分文件请求映射到 Spring 集成时,它会失败。 有关 Spring 对 的支持的更多信息,请参阅 Spring 参考手册。 |
如果您希望将 a 代理到另一台服务器,最好将其保留为原始形式。 要处理这种情况,请不要将 Bean 添加到上下文中。 将端点配置为需要请求,自定义消息转换器以包含 ,并禁用默认的多部分转换器。 您可能需要一些其他转换器来回复。 以下示例显示了这样的安排: <int-http:inbound-gateway |
向客户端发送响应时,可通过多种方式自定义网关的行为。 默认情况下,网关通过发回状态代码来确认已收到请求。 可以通过提供由Spring MVC解析的“viewName”来自定义此响应。 如果网关需要对 的回复,则可以设置标志(构造函数参数)以使网关在创建 HTTP 响应之前等待回复。 以下示例将网关配置为具有视图名称的 Spring MVC 控制器:200
ViewResolver
Message
expectReply
Message
<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>
由于 的值,它会等待回复。 前面的示例还演示如何自定义网关默认接受的 HTTP 方法。constructor-arg
true
POST
GET
回复消息在模型图中可用。 默认情况下,该映射条目的键为“reply”,但您可以通过在端点的配置上设置 “replyKey” 属性来覆盖此默认值。
有效负载验证
从版本 5.2 开始,可以为 HTTP 入站终端节点提供 ,以便在发送到通道之前检查有效负载。 此有效负载已经是转换和提取的结果,以缩小有关有价值数据的验证范围。 验证失败处理与Spring MVC错误处理完全相同。Validator
payloadExpression
HTTP 出站组件
本节介绍 Spring 集成的 HTTP 出站组件。
用HttpRequestExecutingMessageHandler
要配置 ,请编写类似于以下内容的 Bean 定义:HttpRequestExecutingMessageHandler
<bean id="httpOutbound"
class="org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler">
<constructor-arg value="http://localhost:8080/example" />
<property name="outputChannel" ref="responseChannel" />
</bean>
此 Bean 定义通过委托给 . 反过来,该模板委托给实例列表,以从有效负载生成 HTTP 请求正文。 您可以配置这些转换器以及要使用的实例,如以下示例所示:RestTemplate
HttpMessageConverter
Message
ClientHttpRequestFactory
<bean id="httpOutbound"
class="org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler">
<constructor-arg value="http://localhost:8080/example" />
<property name="outputChannel" ref="responseChannel" />
<property name="messageConverters" ref="messageConverterList" />
<property name="requestFactory" ref="customRequestFactory" />
</bean>
缺省情况下,HTTP 请求是使用 的实例生成的,该实例使用 JDK。 Apache Commons HTTP 客户端的使用也支持通过 ,您可以注入该客户端(如前所示)。SimpleClientHttpRequestFactory
HttpURLConnection
CommonsClientHttpRequestFactory
对于出站网关,网关生成的回复消息包含请求消息中存在的所有消息标头。 |
使用饼干
基本 Cookie 支持由出站网关上的属性提供。 设置为 (默认值为 ) 时,在响应中从服务器接收的标头将转换为回复消息中的标头。 然后,此标头将用于后续发送。 这样可以实现简单的有状态交互,如下所示:transfer-cookies
true
false
Set-Cookie
Cookie
…→logonGateway→…→doWorkGateway→…→logoffGateway→…
如果是,则收到的任何标头都保持与回复消息中一样,并在后续发送时删除。transfer-cookies
false
Set-Cookie
Set-Cookie
空响应正文 HTTP 是一种请求-响应协议。 但是,响应可能没有正文,只有标头。 在这种情况下,生成的回复有效负载为 ,无论提供任何 . 根据 HTTP RFC 状态代码定义,有许多状态要求响应不得包含消息正文(例如,)。 在某些情况下,对同一 URL 的调用可能会也可能不会返回响应正文。 例如,对 HTTP 资源的第一个请求返回内容,但第二个请求不返回内容(返回 )。 但是,在所有情况下,都会填充邮件头。 这可以在 HTTP 出站网关之后的某些路由逻辑中使用。 您还可以使用“有效负载类型路由器/>”<将带有 a 的消息路由到与用于正文响应的消息不同的流。 |
预期响应类型 除了前面关于空响应正文的说明之外,如果响应确实包含正文,则必须提供适当的属性,否则再次收到没有正文的属性。 必须与响应中的(已配置或默认)实例和标头兼容。 这可以是抽象类,甚至可以是接口(例如,当您使用 Java 序列化和 时)。 |
从版本 5.5 开始,公开一个标志(默认情况下)以仅返回响应正文,或将整体作为回复消息有效负载返回,独立于提供的 . 如果 中不存在主体,则忽略此标志并返回整体。HttpRequestExecutingMessageHandler
extractResponseBody
true
ResponseEntity
expectedResponseType
ResponseEntity
ResponseEntity
HTTP 命名空间支持
Spring 集成提供了一个命名空间和相应的模式定义。 若要将其包含在配置中,请在应用程序上下文配置文件中提供以下命名空间声明:http
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/http
https://www.springframework.org/schema/integration/http/spring-integration-http.xsd">
...
</beans>
入境
XML 命名空间提供了两个用于处理 HTTP 入站请求的组件:和 。 要在不返回专用响应的情况下处理请求,请使用 . 以下示例演示如何配置一个:inbound-channel-adapter
inbound-gateway
inbound-channel-adapter
<int-http:inbound-channel-adapter id="httpChannelAdapter" channel="requests"
supported-methods="PUT, DELETE"/>
要处理需要响应的请求,请使用 . 以下示例演示如何配置一个:inbound-gateway
<int-http:inbound-gateway id="inboundGateway"
request-channel="requests"
reply-channel="responses"/>
请求映射支持
Spring Integration 3.0 通过引入 IntegrationRequestMappingHandlerMapping 改进了 REST 支持。 该实现依赖于 Spring Framework 3.1 或更高版本提供的增强型 REST 支持。 |
HTTP 入站网关或 HTTP 入站通道适配器的解析会注册类型为 IntegrationRequestMappingHandlerMapping(如果尚未注册)的 Bean。 HandlerMapping 的这个特定实现将其逻辑委托给 RequestMappingInfoHandlerMapping。 该实现提供了类似于Spring MVC中的org.springframework.web.bind.annotation.RequestMapping注释的功能。integrationRequestMappingHandlerMapping
有关更多信息,请参阅 使用 @RequestMapping 映射请求。 |
为此,Spring Integration 3.0 引入了该元素。 您可以将此可选元素添加到 和 中。 它与 和 属性结合使用。 以下示例演示如何在入站网关上配置它:<request-mapping>
<http:inbound-channel-adapter>
<http:inbound-gateway>
path
supported-methods
<inbound-gateway id="inboundController"
request-channel="requests"
reply-channel="responses"
path="/foo/fooId"
supported-methods="GET"
view-name="foo"
error-code="oops">
<request-mapping headers="User-Agent"
params="myParam=myValue"
consumes="application/json"
produces="!text/plain"/>
</inbound-gateway>
基于上述配置,命名空间解析器创建 的实例(如果不存在)和 Bean,并与其关联 RequestMap 的实例。 反过来,这个实例被转换为Spring MVC RequestMappingInfo。IntegrationRequestMappingHandlerMapping
HttpRequestHandlingController
RequestMapping
该元素提供以下属性:<request-mapping>
-
headers
-
params
-
consumes
-
produces
使用 或 的 and 属性,属性直接转换为 Spring MVC 中的注释提供的相应选项。path
supported-methods
<http:inbound-channel-adapter>
<http:inbound-gateway>
<request-mapping>
org.springframework.web.bind.annotation.RequestMapping
该元素允许您将多个 Spring Integration HTTP 入站端点配置为相同(甚至相同),并允许您根据传入的 HTTP 请求提供不同的下游消息流。<request-mapping>
path
supported-methods
或者,您也可以只声明一个HTTP入站端点,并在Spring 集成流中应用路由和过滤逻辑以实现相同的结果。 这使您可以尽早进入流程。 以下示例演示如何执行此操作:Message
<int-http:inbound-gateway request-channel="httpMethodRouter"
supported-methods="GET,DELETE"
path="/process/entId"
payload-expression="#pathVariables.entId"/>
<int:router input-channel="httpMethodRouter" expression="headers.http_requestMethod">
<int:mapping value="GET" channel="in1"/>
<int:mapping value="DELETE" channel="in2"/>
</int:router>
<int:service-activator input-channel="in1" ref="service" method="getEntity"/>
<int:service-activator input-channel="in2" ref="service" method="delete"/>
有关处理程序映射的更多信息,请参阅 Spring Framework Web Servlet 文档或 Spring Framework Web Reactive 文档。
它扩展了Spring MVC类,继承了它的大部分逻辑,特别是当映射由于某种原因不匹配时,它会为HTTP响应抛出特定的错误,从而阻止调用应用程序上下文中任何剩余的映射处理程序。 出于这个原因,为Spring Integration和Spring MVC请求映射配置相同的路径(例如 在一个和另一个)不受支持;将找不到 MVC 映射。. |
跨源资源共享 (CORS) 支持
从版本 4.2 开始,您可以配置 和 with 元素。 它代表了与Spring MVC相同的注释选项,并允许为Spring Integration HTTP端点配置跨源资源共享(CORS):<http:inbound-channel-adapter>
<http:inbound-gateway>
<cross-origin>
@CrossOrigin
@Controller
-
origin
:允许的来源列表。 这意味着允许所有来源。 这些值放置在预飞行和实际响应的标头中。 默认值为 。*
Access-Control-Allow-Origin
*
-
allowed-headers
:指示在实际请求期间可以使用哪些请求标头。 这意味着允许客户端请求的所有标头。 此属性控制预检响应标头的值。 默认值为 。*
Access-Control-Allow-Headers
*
-
exposed-headers
:用户代理允许客户端访问的响应标头列表。 此属性控制实际响应标头的值。Access-Control-Expose-Headers
-
method
:允许的 HTTP 请求方法:、、、、。 此处指定的方法将覆盖 中的方法。GET
POST
HEAD
OPTIONS
PUT
PATCH
DELETE
TRACE
supported-methods
-
allow-credentials
:设置为浏览器是否应包含与请求域关联的任何 Cookie,或者是否应包含。 空字符串 (“”) 表示未定义。 如果 ,则预检响应包括标头。 默认值为 。true
false
true
Access-Control-Allow-Credentials=true
true
-
max-age
:控制预检响应的缓存持续时间。 将此值设置为合理的值可以减少浏览器所需的预检请求-响应交互次数。 此属性控制预检响应中标头的值。 值 表示未定义。 默认值为 1800 秒(30 分钟)。Access-Control-Max-Age
-1
CORS Java 配置由类表示,类的实例可以注入到 bean 中。org.springframework.integration.http.inbound.CrossOrigin
HttpRequestHandlingEndpointSupport
响应状态代码
从版本 4.1 开始,您可以使用 配置 以覆盖默认状态。 表达式必须返回可转换为枚举值的对象。 从版本 5.1 开始,具有 and 与 as 根对象一起提供。 例如,在运行时解析某个返回状态代码值的作用域 Bean。 但是,它很可能设置为固定值,例如(无内容)或 . 默认情况下,为 null,表示返回正常的“200 OK”响应状态。 使用 as 根对象,状态代码可以是有条件的,例如在请求方法、某些标头、URI 内容甚至请求正文上。 下面的示例演示如何将状态代码设置为 :<http:inbound-channel-adapter>
status-code-expression
200 OK
org.springframework.http.HttpStatus
evaluationContext
BeanResolver
RequestEntity<?>
status-code=expression="204"
status-code-expression="T(org.springframework.http.HttpStatus).NO_CONTENT"
status-code-expression
RequestEntity<?>
ACCEPTED
<http:inbound-channel-adapter id="inboundController"
channel="requests" view-name="foo" error-code="oops"
status-code-expression="T(org.springframework.http.HttpStatus).ACCEPTED">
<request-mapping headers="BAR"/>
</http:inbound-channel-adapter>
从回复的标头解析“状态代码”。 从版本 4.2 开始,在 中未收到回复时的默认响应状态代码为 。 有两种方法可以修改此行为:<http:inbound-gateway>
http_statusCode
Message
reply-timeout
500 Internal Server Error
- 添加 . 这与入站适配器上的语义相同。
reply-timeout-status-code-expression
status-code-expression
- 添加 并返回带有 HTTP 状态代码标头的相应消息,如以下示例所示:
error-channel
<int:chain input-channel="errors">
<int:header-enricher>
<int:header name="http_statusCode" value="504" />
</int:header-enricher>
<int:transformer expression="payload.failedMessage" />
</int:chain>
的有效负载为 . 必须将其转换为可由网关转换的内容,例如 . 一个很好的候选项是异常的消息属性,它是使用该技术时使用的值。ErrorMessage
MessageTimeoutException
String
expression
如果错误流在主流超时后超时,则返回,或者,如果存在,则对其进行评估。500 Internal Server Error
reply-timeout-status-code-expression
以前,超时的默认状态代码为 。 要恢复该行为,请设置 。 |
同样从版本 5.4 开始,准备请求消息时遇到的错误将发送到错误通道(如果提供)。 有关引发适当异常的决定应通过检查异常在错误流中完成。 以前,任何异常都只是抛出,导致 HTTP 500 服务器错误响应状态,但在某些情况下,问题可能是由不正确的请求参数引起的,因此应改为抛出具有 4xx 客户端错误状态的 。 有关详细信息,请参阅。 发送到此错误通道包含原始异常作为分析的有效负载。 ==== URI 模板变量和表达式ResponseStatusException
ResponseStatusException
ErrorMessage
通过将属性与属性和元素结合使用,可以高度灵活地映射入站请求数据。path
payload-expression
header
在以下示例配置中,入站通道适配器配置为使用以下 URI 接受请求:
/first-name/firstName/last-name/lastName
使用该属性时,URI 模板变量映射到有效负载,而 URI 模板变量映射到消息头,如以下示例中所定义:payload-expression
firstName
Message
lastName
lname
<int-http:inbound-channel-adapter id="inboundAdapterWithExpressions"
path="/first-name/firstName/last-name/lastName"
channel="requests"
payload-expression="#pathVariables.firstName">
<int-http:header name="lname" expression="#pathVariables.lastName"/>
</int-http:inbound-channel-adapter>
有关 URI 模板变量的更多信息,请参阅 Spring 参考手册中的 URI 模板模式。
从 Spring Integration 3.0 开始,除了有效负载和标头表达式中可用的现有变量和变量之外,我们还添加了其他有用的表达式变量:#pathVariables
#requestParams
-
#requestParams
:来自 .MultiValueMap
ServletRequest
parameterMap
-
#pathVariables
:来自 URI 模板占位符及其值。Map
-
#matrixVariables
:根据Spring MVC规范。 请注意,这需要 Spring MVC 3.2 或更高版本。Map
MultiValueMap
#matrixVariables
-
#requestAttributes
:与当前请求关联的。org.springframework.web.context.request.RequestAttributes
-
#requestHeaders
:当前请求中的对象。org.springframework.http.HttpHeaders
-
#cookies
:当前请求中的实例数。MultiValueMap<String, Cookie>
jakarta.servlet.http.Cookie
请注意,如果下游消息流是单线程的并且位于请求线程中,则可以在下游消息流的表达式中通过变量访问所有这些值(和其他值)。 下面的示例配置使用属性的转换器:ThreadLocal
org.springframework.web.context.request.RequestAttributes
expression
<int-:transformer
expression="T(org.springframework.web.context.request.RequestContextHolder).
requestAttributes.request.queryString"/>
出境
若要配置出站网关,可以使用命名空间支持。 以下代码片段显示了出站 HTTP 网关的可用配置选项:
<int-http:outbound-gateway id="example"
request-channel="requests"
url="http://localhost/test"
http-method="POST"
extract-request-payload="false"
expected-response-type="java.lang.String"
charset="UTF-8"
request-factory="requestFactory"
reply-timeout="1234"
reply-channel="replies"/>
最重要的是,请注意提供了“http-method”和“预期响应类型”属性。 这是两个最常配置的值。 默认值为 ,默认响应类型为 null。 对于 null
以上是关于Spring Integration的HTTP支持的主要内容,如果未能解决你的问题,请参考以下文章
spring-integration-smb 是不是支持 SMB2 和 SMB3?
使用 spring-integration-dsl 的动态 http 入站网关
无法找到 XML 模式命名空间的 Spring NamespaceHandler [http://www.springframework.org/schema/integration/twitter]