Spring Integration 提供了命名空间和相应的模式定义。
若要将其包含在配置中,请在应用程序上下文配置文件中提供以下命名空间声明: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 的实例,并将 RequestMapping
的实例与它相关联。
此实例又转换为 Spring MVC RequestMappingInfo
。IntegrationRequestMappingHandlerMapping
HttpRequestHandlingController
RequestMapping
该元素提供以下属性:<request-mapping>
-
headers
-
params
-
consumes
-
produces
使用 和 的 和 属性 或 ,属性直接转换为 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 Integration 流中应用路由和过滤逻辑以实现相同的结果。
这使您可以尽早进入流程。
以下示例演示如何执行此操作: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 映射。IntegrationRequestMappingHandlerMapping RequestMappingHandlerMapping handleNoMatch(Set, String, HttpServletRequest) 4xx POST GET |
Spring Integration 3.0 通过引入 IntegrationRequestMappingHandlerMapping 改进了 REST 支持。
该实现依赖于 Spring Framework 3.1 或更高版本提供的增强的 REST 支持。 |
有关更多信息,请参阅使用 @RequestMapping 映射请求。 |
扩展了 Spring MVC 类,继承了它的大部分逻辑,特别是 ,当映射由于某种原因不匹配时,它会为 HTTP 响应抛出特定错误,从而阻止对应用程序上下文中任何剩余映射处理程序的调用。
因此,为 Spring Integration 和 Spring MVC 请求映射配置相同的路径(例如 在一个和另一个中)不受支持;找不到 MVC 映射。IntegrationRequestMappingHandlerMapping RequestMappingHandlerMapping handleNoMatch(Set, String, HttpServletRequest) 4xx POST GET |
跨域资源共享 (CORS) 支持
从版本 4.2 开始,您可以使用元素配置 and。
它表示与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 开始,您可以配置 with a 以覆盖默认状态。
表达式必须返回一个可转换为枚举值的对象。
从版本 5.1 开始,具有 and 作为根对象提供。
例如,在运行时解析返回状态代码值的某些作用域 Bean。
但是,最有可能的是,它被设置为固定值,例如 (无内容) 或 .
默认情况下,为 null,表示返回正常的“200 OK”响应状态。
使用 as root 对象,状态代码可以是有条件的,例如请求方法、某些标头、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
以前,超时的默认状态代码为 。
若要恢复该行为,请设置 。200 OK reply-timeout-status-code-expression="200" |
同样从 V5.4 开始,准备请求消息时遇到的错误将发送到错误通道(如果提供)。
应通过检查异常在错误流中决定是否引发适当的异常。
以前,任何异常都只是简单地抛出,导致 HTTP 500 服务器错误响应状态,但在某些情况下,问题可能是由不正确的请求参数引起的,因此应抛出具有 4xx 客户端错误状态的异常。
有关详细信息,请参阅。
发送到此错误通道包含原始异常作为分析的有效负载。ResponseStatusException
ResponseStatusException
ErrorMessage
以前,超时的默认状态代码为 。
若要恢复该行为,请设置 。200 OK reply-timeout-status-code-expression="200" |
URI 模板变量和表达式
通过将该属性与属性和元素结合使用,可以高度灵活地映射入站请求数据。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 开始,除了 payload 和 header 表达式中可用的现有变量和变量外,我们还添加了其他有用的表达式变量:#pathVariables
#requestParams
-
#requestParams
:来自 .MultiValueMap
ServletRequest
parameterMap
-
#pathVariables
:from URI 模板占位符及其值。Map
-
#matrixVariables
:根据 Spring MVC 规范的 of。 请注意,这需要 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”和“expected-response-type”属性。
这是两个最常配置的值。
默认值为 ,默认响应类型为 null。
对于 null 响应类型,只要其 HTTP 状态为 成功(不成功的状态代码会引发异常),回复的有效负载就包含 。
如果需要其他类型(如 ,请将其作为完全限定的类名提供)(在前面的示例中)。
另请参阅有关 HTTP 出站组件中空响应正文的说明。http-method
POST
Message
ResponseEntity
String
java.lang.String
从 Spring Integration 2.1 开始,HTTP 出站网关的属性被重命名,以更好地反映其意图。request-timeout reply-timeout |
从 Spring Integration 2.2 开始,默认情况下不再启用基于 HTTP 的 Java 序列化。
以前,将属性设置为对象时,标头未正确设置。
从 Spring Integration 2.2 开始,现在已经更新了标头,将标头设置为 。 但是,由于这可能会导致与现有应用程序不兼容,因此决定不再自动将此转换器添加到 HTTP 终结点。
如果要使用 Java 序列化,可以使用属性(使用 XML 配置时)或使用方法(在 Java 配置中)将 添加到相应的端点。
或者,您可能希望考虑改用 JSON,这是通过在类路径上放置 Jackson 库来启用的。 |
从 Spring Integration 2.2 开始,您还可以使用 SpEL 和属性动态确定 HTTP 方法。
请注意,此属性与 互斥。
您还可以使用该属性来代替并提供任何确定响应类型的有效 SpEL 表达式。
以下配置示例使用:http-method-expression
http-method
expected-response-type-expression
expected-response-type
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 表达式,以 the 作为根对象,用于启用动态 url。
表达式计算结果的 URL 仍可以具有 URI 变量的占位符。 在以前的版本中,一些用户使用占位符将整个 URL 替换为 URI 变量。 Spring 3.1 中的更改可能会导致转义字符出现一些问题,例如“?”。 因此,如果您希望完全在运行时生成 URL,我们建议您使用“url-expression”属性。 |
从 Spring Integration 2.1 开始,HTTP 出站网关的属性被重命名,以更好地反映其意图。request-timeout reply-timeout |
从 Spring Integration 2.2 开始,默认情况下不再启用基于 HTTP 的 Java 序列化。
以前,将属性设置为对象时,标头未正确设置。
从 Spring Integration 2.2 开始,现在已经更新了标头,将标头设置为 。 但是,由于这可能会导致与现有应用程序不兼容,因此决定不再自动将此转换器添加到 HTTP 终结点。
如果要使用 Java 序列化,可以使用属性(使用 XML 配置时)或使用方法(在 Java 配置中)将 添加到相应的端点。
或者,您可能希望考虑改用 JSON,这是通过在类路径上放置 Jackson 库来启用的。 |
要指定 URL,您可以使用“url”属性或“url-expression”属性。
“url”属性采用一个简单的字符串(带有 URI 变量的占位符,如下所述)。
“url-expression”是一个 SpEL 表达式,以 the 作为根对象,用于启用动态 url。
表达式计算结果的 URL 仍可以具有 URI 变量的占位符。 在以前的版本中,一些用户使用占位符将整个 URL 替换为 URI 变量。 Spring 3.1 中的更改可能会导致转义字符出现一些问题,例如“?”。 因此,如果您希望完全在运行时生成 URL,我们建议您使用“url-expression”属性。 |
映射 URI 变量
如果 URL 包含 URI 变量,则可以使用该元素映射它们。
此元素可用于 HTTP 出站网关和 HTTP 出站通道适配器。
以下示例将 URI 变量映射到表达式:uri-variable
zipCode
<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 变量的名称,而该属性用于设置实际值。
通过使用该属性,您可以利用 Spring 表达式语言 (SpEL) 的全部功能,它使您可以完全动态访问消息有效负载和消息标头。
例如,在前面的配置中,该方法在 的有效负载对象上调用,该方法的结果用作名为“zipCode”的 URI 变量的值。uri-variable
name
expression
name
expression
expression
getZip()
Message
从 Spring Integration 3.0 开始,HTTP 出站端点支持该属性来指定应评估的属性,从而在 URL 模板中生成所有 URI 变量占位符。
它提供了一种机制,您可以在其中根据出站消息使用不同的变量表达式。
此属性与元素互斥。
下面的示例演示如何使用该属性:uri-variables-expression
expression
Map
<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 变量占位符的进一步解析。uri-variables-expression Map Map String Expression Map ExpressionEvalMap Message |
重要
该属性提供了一种非常强大的机制来计算 URI 变量。
我们预计人们大多使用简单的表达式,例如前面的示例。
但是,您也可以配置一些内容,例如在返回的映射中将表达式设置为 ,其中表达式在名为 的消息头中动态提供。
由于标头可能来自不受信任的源,因此 HTTP 出站终结点在评估这些表达式时使用。
仅使用 SpEL 功能的子集。
如果您信任消息源并希望使用受限制的 SpEL 构造,请将出站终结点的属性设置为 。uriVariablesExpression
"@uriVariablesBean.populate(#root)"
variables.put("thing1", EXPRESSION_PARSER.parseExpression(message.getHeaders().get("thing2", String.class)));
thing2
SimpleEvaluationContext
SimpleEvaluationContext
trustedSpel
true
通过使用自定义和一些实用程序来构建和编码 URL 参数,可以实现需要基于每条消息提供一组动态 URI 变量的方案。
以下示例演示如何执行此操作:url-expression
url-expression="T(org.springframework.web.util.UriComponentsBuilder)
.fromHttpUrl('https://HOST:PORT/PATH')
.queryParams(payload)
.build()
.toUri()"
该方法需要 a 作为参数,因此您可以在执行请求之前提前构建一组真实的 URL 查询参数。queryParams()
MultiValueMap<String, String>
整体也可以表示为 ,如以下示例所示: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 编码。
例如,您可以将 用于此目的。
如前所述,可以使用以下 Java Streams 代码段将手动构建的参数转换为 method 参数:org.apache.http.client.utils.URLEncodedUtils#format()
MultiValueMap<String, String>
List<NameValuePair>
format()
List<NameValuePair> nameValuePairs =
params.entrySet()
.stream()
.flatMap(e -> e
.getValue()
.stream()
.map(v -> new BasicNameValuePair(e.getKey(), v)))
.collect(Collectors.toList());
必须计算为 .
的值必须是 或 的实例。
通过在出站的上下文中使用这些表达式,将其提供给 URI 变量占位符的进一步解析。uri-variables-expression Map Map String Expression Map ExpressionEvalMap Message |
控制 URI 编码
默认情况下,在发送请求之前,URL 字符串将编码为 URI 对象(请参阅 UriComponentsBuilder
)。
在某些具有非标准 URI(例如 RabbitMQ REST API)的方案中,不需要执行编码。
和 提供属性。
若要禁用对 URL 的编码,请将此属性设置为(默认情况下为 )。
如果要对 URL 的某些部分进行部分编码,请在 中使用 ,如以下示例所示:<http:outbound-gateway/>
<http:outbound-channel-adapter/>
encoding-mode
NONE
TEMPLATE_AND_VALUES
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,此选项可以通过该选项进行控制。
相同的配置适用于 WebFlux 模块和 Web 服务模块中的类似出站组件。
对于许多复杂的场景,建议在外部提供 ;或者在 WebFlux 的情况下 - 使用它.BaseHttpMessageHandlerSpec.encodingMode()
UriTemplateHandler
RestTemplate
WebClient
UriBuilderFactory