此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.4.3! |
HTTP 命名空间支持
Spring 集成提供了一个http
namespace 和相应的 schema definition 创建。
要将其包含在您的配置中,请在您的应用程序上下文配置文件中提供以下命名空间声明:
<?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 .
该实现依赖于 Spring Framework 3.1 或更高版本提供的增强 REST 支持。 |
HTTP 入站网关或 HTTP 入站通道适配器的解析会注册一个integrationRequestMappingHandlerMapping
类型的 beanIntegrationRequestMappingHandlerMapping
,以防尚未注册。
这个HandlerMapping
将其 logic 委托给RequestMappingInfoHandlerMapping
.
该实现提供类似于org.springframework.web.bind.annotation.RequestMapping
注解。
有关更多信息,请参阅将请求映射到@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>
根据前面的配置,命名空间解析器会创建一个IntegrationRequestMappingHandlerMapping
(如果不存在)和HttpRequestHandlingController
bean 并与之关联的RequestMapping
.
这RequestMapping
实例反过来又转换为 Spring MVCRequestMappingInfo
.
这<request-mapping>
元素提供以下属性:
-
headers
-
params
-
consumes
-
produces
使用path
和supported-methods
的属性<http:inbound-channel-adapter>
或<http:inbound-gateway>
,<request-mapping>
attributes 直接转换为org.springframework.web.bind.annotation.RequestMapping
注解。
这<request-mapping>
元素允许您将多个 Spring 集成 HTTP 入站端点配置为相同的path
(甚至相同supported-methods
),并允许根据传入的 HTTP 请求提供不同的下游消息流。
或者,你也可以只声明一个 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 文档。
这IntegrationRequestMappingHandlerMapping 扩展 Spring MVCRequestMappingHandlerMapping 类,继承了它的大部分逻辑,尤其是handleNoMatch(Set, String, HttpServletRequest) ,它会抛出一个特定的4xx 当映射由于某种原因不匹配时,HTTP 响应的错误,阻止调用应用程序上下文中任何剩余的映射处理程序。
出于这个原因,为 Spring Integration 和 Spring MVC 请求映射配置相同的路径(例如POST 合一和GET 在另一个)不受支持;找不到 MVC 映射.. |
跨域资源共享 (CORS) 支持
从版本 4.2 开始,您可以配置<http:inbound-channel-adapter>
和<http:inbound-gateway>
替换为<cross-origin>
元素。
它表示与 Spring MVC 的@CrossOrigin
为@Controller
注释并允许为 Spring 集成 HTTP 端点配置跨域资源共享 (CORS):
-
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
:设置为true
如果浏览器应包含与请求的域关联的任何 Cookie,或者false
如果不应该。 空字符串 (“”) 表示未定义。 如果true
,则飞行前响应包括Access-Control-Allow-Credentials=true
页眉。 默认值为true
. -
max-age
:控制飞行前响应的缓存持续时间。 将此值设置为合理的值可以减少浏览器所需的飞行前请求-响应交互的数量。 此属性控制Access-Control-Max-Age
标头。 值-1
表示 undefined。 默认值为 1800 秒(30 分钟)。
CORS Java 配置由org.springframework.integration.http.inbound.CrossOrigin
类,其实例可以注入到HttpRequestHandlingEndpointSupport
豆。
响应状态代码
从版本 4.1 开始,您可以配置<http:inbound-channel-adapter>
替换为status-code-expression
以覆盖默认值200 OK
地位。
表达式必须返回一个可以转换为org.springframework.http.HttpStatus
enum 值。
这evaluationContext
具有BeanResolver
并且,从版本 5.1 开始,随RequestEntity<?>
作为根对象。
例如,在运行时解决一些返回状态代码值的作用域 bean。
但是,它很可能被设置为一个固定值,例如status-code=expression="204"
(无内容),或status-code-expression="T(org.springframework.http.HttpStatus).NO_CONTENT"
.
默认情况下,status-code-expression
为 null,则表示返回正常的 '200 OK' 响应状态。
使用RequestEntity<?>
作为根对象,状态码可以是有条件的,例如在请求方法、某些标头、URI 内容甚至请求正文上。
以下示例演示如何将状态代码设置为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>
这<http:inbound-gateway>
解析http_statusCode
回复的标头Message
.
从版本 4.2 开始,当在reply-timeout
是500 Internal Server Error
.
有两种方法可以修改此行为:
-
添加
reply-timeout-status-code-expression
. 这与status-code-expression
在入站适配器上。 -
添加
error-channel
并返回带有 HTTP 状态代码标头的相应消息,如下例所示:<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
.
一个很好的候选对象是异常的 message 属性,这是您在使用expression
技术。
如果错误流在主流超时后超时,500 Internal Server Error
返回,或者,如果返回reply-timeout-status-code-expression
存在,则对其进行评估。
以前,超时的默认状态代码为200 OK .
要恢复该行为,请将reply-timeout-status-code-expression="200" . |
同样从版本 5.4 开始,准备请求消息时遇到的错误将发送到错误通道(如果提供)。
应该通过检查异常来决定在错误流中引发适当的异常。
以前,任何异常都只是简单地抛出,导致 HTTP 500 服务器错误响应状态,但在某些情况下,问题可能是由不正确的请求参数引起的,因此ResponseStatusException
对于 4xx 客户端错误,应改为引发 status。
看ResponseStatusException
了解更多信息。
这ErrorMessage
sent to this error 通道包含原始异常作为 analysis 的有效负载。
URI 模板变量和表达式
通过使用path
属性与payload-expression
属性和header
元素中,您可以高度灵活地映射入站请求数据。
在以下示例配置中,入站通道适配器配置为使用以下 URI 接受请求:
/first-name/{firstName}/last-name/{lastName}
当您使用payload-expression
属性、{firstName}
URI 模板变量映射到Message
payload 的{lastName}
URI 模板变量映射到lname
message 标头,如以下示例中所定义:
<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 Reference Manual 中的 uri 模板模式。
从 Spring Integration 3.0 开始,除了现有的#pathVariables
和#requestParams
变量中,我们添加了其他有用的表达式变量:
-
#requestParams
:这MultiValueMap
从ServletRequest
parameterMap
. -
#pathVariables
:这Map
从 URI 模板占位符及其值。 -
#matrixVariables
:这Map
之MultiValueMap
根据 Spring MVC 规范。 请注意,#matrixVariables
需要 Spring MVC 3.2 或更高版本。 -
#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
variable,如果该消息流是单线程的并且位于请求线程中。
以下示例配置一个使用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' 和 'expected-response-type' 属性。
这是两个最常见的配置值。
默认的http-method
是POST
,默认响应类型为 null。
对于 null 响应类型,则回复的有效负载Message
包含ResponseEntity
,只要其 HTTP 状态为 successful(不成功的状态代码会引发异常)。
如果您需要不同的类型,例如String
,将其作为完全限定的类名 (java.lang.String
在前面的示例中)。
另请参阅有关 HTTP 出站组件中空响应正文的说明。
从 Spring Integration 2.1 开始,request-timeout HTTP 出站网关的属性已重命名为reply-timeout 以更好地反映其意图。 |
从 Spring Integration 2.2 开始,默认情况下不再启用基于 HTTP 的 Java 序列化。
以前,在设置 但是,由于这可能会导致与现有应用程序不兼容,因此决定不再自动将此转换器添加到 HTTP 端点。
如果您希望使用 Java 序列化,则可以添加 |
从 Spring Integration 2.2 开始,你还可以使用 SPEL 和http-method-expression
属性。
请注意,此属性与http-method
.
您还可以使用expected-response-type-expression
属性而不是expected-response-type
并提供确定响应类型的任何有效 SpEL 表达式。
以下配置示例使用expected-response-type-expression
:
<int-http:outbound-gateway id="example"
request-channel="requests"
url="http://localhost/test"
http-method-expression="headers.httpMethod"
extract-request-payload="false"
expected-response-type-expression="payload"
charset="UTF-8"
request-factory="requestFactory"
reply-timeout="1234"
reply-channel="replies"/>
如果您的出站适配器要以单向方式使用,您可以使用outbound-channel-adapter
相反。
这意味着成功的响应执行时不会向回复通道发送任何消息。
如果出现任何不成功的响应状态代码,则会引发异常。
该配置看起来与网关非常相似,如下例所示:
<int-http:outbound-channel-adapter id="example"
url="http://localhost/example"
http-method="GET"
channel="requests"
charset="UTF-8"
extract-payload="false"
expected-response-type="java.lang.String"
request-factory="someRequestFactory"
order="3"
auto-startup="false"/>
要指定 URL,您可以使用 'url' 属性或 'url-expression' 属性。
'url' 属性采用一个简单的字符串(带有 URI 变量的占位符,如下所述)。
'url-expression' 是一个 SpEL 表达式,其中 在以前的版本中,一些用户使用占位符将整个 URL 替换为 URI 变量。 Spring 3.1 中的更改可能会导致一些转义字符问题,例如 '?'。 因此,如果您希望完全在运行时生成 URL,我们建议您使用 'url-expression' 属性。 |
映射 URI 变量
如果您的 URL 包含 URI 变量,则可以使用uri-variable
元素。
此元素可用于 HTTP 出站网关和 HTTP 出站通道适配器。
以下示例映射zipCode
URI 变量添加到表达式中:
<int-http:outbound-gateway id="trafficGateway"
url="https://local.yahooapis.com/trafficData?appid=YdnDemo&zip={zipCode}"
request-channel="trafficChannel"
http-method="GET"
expected-response-type="java.lang.String">
<int-http:uri-variable name="zipCode" expression="payload.getZip()"/>
</int-http:outbound-gateway>
这uri-variable
元素定义两个属性:name
和expression
.
这name
属性标识 URI 变量的名称,而expression
属性用于设置实际值。
通过使用expression
属性,您可以利用 Spring 表达式语言 (SpEL) 的全部功能,它为您提供对消息有效负载和消息标头的完全动态访问。
例如,在前面的配置中,getZip()
方法在Message
,该方法的结果用作名为 'zipCode' 的 URI 变量的值。
从 Spring Integration 3.0 开始,HTTP 出站端点支持uri-variables-expression
属性来指定expression
,从而得到一个Map
URL 模板中所有 URI 变量占位符的 URL 变量占位符。
它提供了一种机制,通过该机制,您可以根据出站消息使用不同的变量表达式。
此属性与<uri-variable/>
元素。
以下示例演示如何使用uri-variables-expression
属性:
<int-http:outbound-gateway
url="https://foo.host/{foo}/bars/{bar}"
request-channel="trafficChannel"
http-method="GET"
uri-variables-expression="@uriVariablesBean.populate(payload)"
expected-response-type="java.lang.String"/>
uriVariablesBean
可能定义如下:
public class UriVariablesBean {
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
public Map<String, ?> populate(Object payload) {
Map<String, Object> variables = new HashMap<String, Object>();
if (payload instanceOf String.class)) {
variables.put("foo", "foo"));
}
else {
variables.put("foo", EXPRESSION_PARSER.parseExpression("headers.bar"));
}
return variables;
}
}
这uri-variables-expression 必须计算为Map .
的Map 必须是String 或Expression .
这Map 提供给ExpressionEvalMap 通过在出站的上下文中使用这些表达式来进一步解析 URI 变量占位符Message . |
重要
这uriVariablesExpression
property 提供了一种非常强大的机制来评估 URI 变量。
我们预计人们主要使用简单的表达式,例如前面的示例。
但是,您也可以配置诸如"@uriVariablesBean.populate(#root)"
返回的 map 中的表达式为variables.put("thing1", EXPRESSION_PARSER.parseExpression(message.getHeaders().get("thing2", String.class)));
,其中表达式在名为thing2
.
由于标头可能来自不受信任的源,因此 HTTP 出站终端节点使用SimpleEvaluationContext
在计算这些表达式时。
这SimpleEvaluationContext
仅使用 SPEL 功能的子集。
如果您信任您的消息源并希望使用受限制的 SPEL 结构,请将trustedSpel
属性设置为true
.
通过使用自定义url-expression
以及一些用于构建和编码 URL 参数的实用程序。
以下示例显示了如何执行此作:
url-expression="T(org.springframework.web.util.UriComponentsBuilder)
.fromHttpUrl('https://HOST:PORT/PATH')
.queryParams(payload)
.build()
.toUri()"
这queryParams()
method 需要一个MultiValueMap<String, String>
作为参数,因此您可以在执行请求之前提前构建一组真实的 URL 查询参数。
整个queryString
也可以显示为uri-variable
,如下例所示:
<int-http:outbound-gateway id="proxyGateway" request-channel="testChannel"
url="http://testServer/test?{queryString}">
<int-http:uri-variable name="queryString" expression="'a=A&b=B'"/>
</int-http:outbound-gateway>
在这种情况下,您必须手动提供 URL 编码。
例如,您可以使用org.apache.http.client.utils.URLEncodedUtils#format()
为此目的。
如前所述,手动构建的MultiValueMap<String, String>
可以转换为List<NameValuePair>
format()
method 参数:
List<NameValuePair> nameValuePairs =
params.entrySet()
.stream()
.flatMap(e -> e
.getValue()
.stream()
.map(v -> new BasicNameValuePair(e.getKey(), v)))
.collect(Collectors.toList());
控制 URI 编码
默认情况下,URL 字符串是编码的(请参阅UriComponentsBuilder
) 添加到 URI 对象。
在某些具有非标准 URI(例如 RabbitMQ REST API)的情况下,不需要执行编码。
这<http:outbound-gateway/>
和<http:outbound-channel-adapter/>
提供encoding-mode
属性。
要禁用 URL 编码,请将此属性设置为NONE
(默认情况下,它是TEMPLATE_AND_VALUES
).
如果您希望对 URL 的某些部分进行部分编码,请使用expression
在<uri-variable/>
,如下例所示:
<http:outbound-gateway url="https://somehost/%2f/fooApps?bar={param}" encoding-mode="NONE">
<http:uri-variable name="param"
expression="T(org.apache.commons.httpclient.util.URIUtil)
.encodeWithinQuery('Hello World!')"/>
</http:outbound-gateway>
对于 Java DSL,此选项可以通过BaseHttpMessageHandlerSpec.encodingMode()
选择。
相同的配置适用于 WebFlux 模块和 Web 服务模块中的类似出站组件。
对于更复杂的场景,建议配置UriTemplateHandler
在外部提供的RestTemplate
;或者,如果是 WebFlux -WebClient
with itUriBuilderFactory
.