对于最新的稳定版本,请使用 Spring Integration 6.4.0spring-doc.cn

HTTP 命名空间支持

Spring 集成提供了一个名称空间和相应的模式定义。 要将其包含在您的配置中,请在您的应用程序上下文配置文件中提供以下命名空间声明:httpspring-doc.cn

<?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-adapterinbound-gatewayinbound-channel-adapterspring-doc.cn

<int-http:inbound-channel-adapter id="httpChannelAdapter" channel="requests"
    supported-methods="PUT, DELETE"/>

要处理需要响应的请求,请使用 . 以下示例显示如何配置一个:inbound-gatewayspring-doc.cn

<int-http:inbound-gateway id="inboundGateway"
    request-channel="requests"
    reply-channel="responses"/>

请求映射支持

Spring 集成 3.0 通过引入IntegrationRequestMappingHandlerMapping改进了 REST 支持。 该实现依赖于 Spring Framework 3.1 或更高版本提供的增强 REST 支持。

HTTP 入站网关或 HTTP 入站通道适配器的解析将注册 IntegrationRequestMappingHandlerMapping 类型的 Bean(如果尚未注册)。 HandlerMapping 的这个特定实现将其逻辑委托给 RequestMappingInfoHandlerMapping。 该实现提供的功能类似于 Spring MVC 中的 org.springframework.web.bind.annotation.RequestMapping 注释。integrationRequestMappingHandlerMappingspring-doc.cn

有关更多信息,请参阅使用 @RequestMapping 映射请求

为此,Spring Integration 3.0 引入了该元素。 您可以将此可选元素添加到 和 中。 它与 和 属性结合使用。 以下示例显示如何在入站网关上配置它:<request-mapping><http:inbound-channel-adapter><http:inbound-gateway>pathsupported-methodsspring-doc.cn

<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 RequestMappingInfoIntegrationRequestMappingHandlerMappingHttpRequestHandlingControllerRequestMappingspring-doc.cn

该元素提供以下属性:<request-mapping>spring-doc.cn

使用或,属性的 and 属性直接转换为 Spring MVC 中的 Comments 提供的相应选项。pathsupported-methods<http:inbound-channel-adapter><http:inbound-gateway><request-mapping>org.springframework.web.bind.annotation.RequestMappingspring-doc.cn

该元素允许您将多个 Spring 集成 HTTP 入站端点配置为相同(甚至相同),并允许您根据传入的 HTTP 请求提供不同的下游消息流。<request-mapping>pathsupported-methodsspring-doc.cn

或者,你也可以只声明一个 HTTP 入站端点,并在 Spring 集成流中应用路由和过滤逻辑来实现相同的结果。 这使您可以尽早进入流程。 以下示例显示了如何执行此操作:Messagespring-doc.cn

<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-doc.cn

它扩展了 Spring MVC 类,继承了它的大部分逻辑,特别是 ,当 map 由于某种原因不匹配时,它会为 HTTP 响应抛出一个特定的错误,从而阻止调用应用程序上下文中任何剩余的 mapping 处理程序。 出于这个原因,为 Spring Integration 和 Spring MVC 请求映射配置相同的路径(例如 在一个和另一个中)不受支持;找不到 MVC 映射..IntegrationRequestMappingHandlerMappingRequestMappingHandlerMappinghandleNoMatch(Set, String, HttpServletRequest)4xxPOSTGET

跨域资源共享 (CORS) 支持

从版本 4.2 开始,您可以使用 element 配置 and。 它表示与 Spring MVC 的 Comments 选项相同,并允许为 Spring 集成 HTTP 端点配置跨域资源共享(CORS):<http:inbound-channel-adapter><http:inbound-gateway><cross-origin>@CrossOrigin@Controllerspring-doc.cn

  • origin:允许的源列表。 表示允许所有源。 这些值都放在 pre-flight 和 actual 响应的标头中。 默认值为 .*Access-Control-Allow-Origin*spring-doc.cn

  • allowed-headers:指示在实际请求期间可以使用哪些请求标头。 这意味着允许客户端请求的所有标头。 此属性控制飞行前响应的 header 的值。 默认值为 .*Access-Control-Allow-Headers*spring-doc.cn

  • exposed-headers:用户代理允许客户端访问的响应标头列表。 此属性控制实际响应标头的值。Access-Control-Expose-Headersspring-doc.cn

  • method:允许的 HTTP 请求方法:、、、、 . 此处指定的方法将覆盖 中的方法。GETPOSTHEADOPTIONSPUTPATCHDELETETRACEsupported-methodsspring-doc.cn

  • allow-credentials:设置为浏览器是否应包含与请求域关联的任何 Cookie,或者是否不应包含。 空字符串 (“”) 表示未定义。 如果 ,则飞行前响应包括 Header。 默认值为 .truefalsetrueAccess-Control-Allow-Credentials=truetruespring-doc.cn

  • max-age:控制飞行前响应的缓存持续时间。 将此值设置为合理的值可以减少浏览器所需的飞行前请求-响应交互的数量。 此属性控制 pre-flight 响应中 header 的值。 值 表示 undefined。 默认值为 1800 秒(30 分钟)。Access-Control-Max-Age-1spring-doc.cn

CORS Java 配置由类表示,该类的实例可以注入到 bean 中。org.springframework.integration.http.inbound.CrossOriginHttpRequestHandlingEndpointSupportspring-doc.cn

响应状态代码

从版本 4.1 开始,您可以使用 a 配置 以覆盖默认状态。 表达式必须返回一个可以转换为枚举值的对象。 从版本 5.1 开始,具有 and,作为 root 对象提供。 例如,在运行时解决一些返回状态代码值的作用域 bean。 但是,它很可能设置为固定值,如 (No Content) 或 . 默认情况下,为 null,表示返回正常的“200 OK”响应状态。 使用 as root 对象,状态代码可以是有条件的,例如在请求方法、某些标头、URI 内容甚至请求正文上。 以下示例显示如何将状态代码设置为 :<http:inbound-channel-adapter>status-code-expression200 OKorg.springframework.http.HttpStatusevaluationContextBeanResolverRequestEntity<?>status-code=expression="204"status-code-expression="T(org.springframework.http.HttpStatus).NO_CONTENT"status-code-expressionRequestEntity<?>ACCEPTEDspring-doc.cn

<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_statusCodeMessagereply-timeout500 Internal Server Errorspring-doc.cn

  • 添加 . 这与入站适配器上的语义相同。reply-timeout-status-code-expressionstatus-code-expressionspring-doc.cn

  • 添加并返回带有 HTTP 状态代码标头的相应消息,如下例所示:error-channelspring-doc.cn

    <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>

的有效负载是一个 . 它必须转换为网关可以转换的内容,例如 . 一个很好的候选对象是异常的 message 属性,这是使用该技术时使用的值。ErrorMessageMessageTimeoutExceptionStringexpressionspring-doc.cn

如果错误流在主流超时后超时,则返回错误流,或者如果存在错误流,则评估错误流。500 Internal Server Errorreply-timeout-status-code-expressionspring-doc.cn

以前,超时的默认状态代码为 。 要恢复该行为,请将 .200 OKreply-timeout-status-code-expression="200"

同样从版本 5.4 开始,准备请求消息时遇到的错误将发送到错误通道(如果提供)。 应该通过检查异常来决定在错误流中引发适当的异常。 以前,任何异常都只是简单地抛出,导致 HTTP 500 服务器错误响应状态,但在某些情况下,问题可能是由不正确的请求参数引起的,因此应该抛出具有 4xx 客户端错误状态的 a。 有关更多信息,请参阅。 发送到此错误通道包含原始异常作为分析的有效负载。ResponseStatusExceptionResponseStatusExceptionErrorMessagespring-doc.cn

URI 模板变量和表达式

通过将 attribute 与 attribute 和 element 结合使用,您可以高度灵活地映射入站请求数据。pathpayload-expressionheaderspring-doc.cn

在以下示例配置中,入站通道适配器配置为使用以下 URI 接受请求:spring-doc.cn

/first-name/{firstName}/last-name/{lastName}

使用该属性时, URI 模板变量 Map 为有效负载,而 URI template 变量映射到消息标头,如以下示例中所定义:payload-expression{firstName}Message{lastName}lnamespring-doc.cn

<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-doc.cn

从 Spring Integration 3.0 开始,除了在有效负载和 Headers 表达式中可用的现有和变量之外,我们还添加了其他有用的表达式变量:#pathVariables#requestParamsspring-doc.cn

  • #requestParams:来自 .MultiValueMapServletRequestparameterMapspring-doc.cn

  • #pathVariables:from URI 模板占位符及其值。Mapspring-doc.cn

  • #matrixVariables:根据 Spring MVC 规范。 请注意,这需要 Spring MVC 3.2 或更高版本。MapMultiValueMap#matrixVariablesspring-doc.cn

  • #requestAttributes:与当前请求关联的。org.springframework.web.context.request.RequestAttributesspring-doc.cn

  • #requestHeaders:当前请求中的对象。org.springframework.http.HttpHeadersspring-doc.cn

  • #cookies:当前请求中的实例。MultiValueMap<String, Cookie>jakarta.servlet.http.Cookiespring-doc.cn

请注意,如果该消息流是单线程的并且位于请求线程中,则所有这些值(和其他值)都可以通过变量在下游消息流的表达式中访问。 以下示例配置使用属性的转换器:ThreadLocalorg.springframework.web.context.request.RequestAttributesexpressionspring-doc.cn

<int-:transformer
    expression="T(org.springframework.web.context.request.RequestContextHolder).
                  requestAttributes.request.queryString"/>

出境

要配置出站网关,您可以使用命名空间支持。 以下代码片段显示了出站 HTTP 网关的可用配置选项:spring-doc.cn

<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 状态为 成功(不成功的状态代码会引发异常)。 如果您需要其他类型,例如 a ,请将其作为完全限定的类名(在前面的示例中为 )。 另请参阅有关 HTTP 出站组件中空响应正文的说明。http-methodPOSTMessageResponseEntityStringjava.lang.Stringspring-doc.cn

从 Spring Integration 2.1 开始,HTTP 出站网关的属性被重命名为以更好地反映其意图。request-timeoutreply-timeout

从 Spring Integration 2.2 开始,默认情况下不再启用基于 HTTP 的 Java 序列化。 以前,在将属性设置为对象时,未正确设置标头。 从 Spring Integration 2.2 开始,现在已经更新为将标头设置为 .expected-response-typeSerializableAcceptSerializingHttpMessageConverterAcceptapplication/x-java-serialized-objectspring-doc.cn

但是,由于这可能会导致与现有应用程序不兼容,因此决定不再自动将此转换器添加到 HTTP 端点。 如果您希望使用 Java 序列化,则可以通过使用属性(当您使用 XML 配置时)或使用方法(在 Java 配置中)将 添加到相应的端点。 或者,您可能希望考虑改用 JSON,这是通过在 Classpath 上使用 Jackson 库来启用的。SerializingHttpMessageConvertermessage-converterssetMessageConverters()spring-doc.cn

从 Spring 集成 2.2 开始,你还可以使用 SPEL 和属性动态确定 HTTP 方法。 请注意,此属性与 是互斥的。 您还可以使用该属性而不是提供任何确定响应类型的有效 SPEL 表达式。 以下配置示例使用:http-method-expressionhttp-methodexpected-response-type-expressionexpected-response-typeexpected-response-type-expressionspring-doc.cn

<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-adapterspring-doc.cn

<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 变量的占位符。Messagespring-doc.cn

在以前的版本中,一些用户使用占位符将整个 URL 替换为 URI 变量。 Spring 3.1 中的更改可能会导致一些转义字符问题,例如 '?'。 因此,如果您希望完全在运行时生成 URL,我们建议您使用 'url-expression' 属性。spring-doc.cn

映射 URI 变量

如果您的 URL 包含 URI 变量,则可以使用该元素映射它们。 此元素可用于 HTTP 出站网关和 HTTP 出站通道适配器。 以下示例将 URI 变量映射到表达式:uri-variablezipCodespring-doc.cn

<int-http:outbound-gateway id="trafficGateway"
    url="https://local.yahooapis.com/trafficData?appid=YdnDemo&amp;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) 的全部功能,这使您可以完全动态地访问消息有效负载和消息标头。 例如,在前面的配置中,在 的 payload 对象上调用该方法,并且该方法的结果用作名为 'zipCode' 的 URI 变量的值。uri-variablenameexpressionnameexpressionexpressiongetZip()Messagespring-doc.cn

从 Spring Integration 3.0 开始,HTTP 出站端点支持该属性来指定应该评估的 an,从而在 URL 模板中产生所有 URI 变量占位符。 它提供了一种机制,通过该机制,您可以根据出站消息使用不同的变量表达式。 此属性与 element 互斥。 以下示例演示如何使用该属性:uri-variables-expressionexpressionMap<uri-variable/>uri-variables-expressionspring-doc.cn

<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可能定义如下:spring-doc.cn

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-expressionMapMapStringExpressionMapExpressionEvalMapMessage

重要 该属性提供了一种非常强大的机制来评估 URI 变量。 我们预计人们主要使用简单的表达式,例如前面的示例。 但是,您也可以配置一些内容,例如在返回的映射中使用表达式 ,其中表达式在名为 的消息标头中动态提供。 由于标头可能来自不受信任的源,因此 HTTP 出站终端节点在评估这些表达式时使用。 它仅使用 SPEL 功能的子集。 如果您信任您的消息源并希望使用受限制的 SPEL 构造,请将出站终端节点的属性设置为 。uriVariablesExpression"@uriVariablesBean.populate(#root)"variables.put("thing1", EXPRESSION_PARSER.parseExpression(message.getHeaders().get("thing2", String.class)));thing2SimpleEvaluationContextSimpleEvaluationContexttrustedSpeltruespring-doc.cn

通过使用自定义和一些实用程序来构建和编码 URL 参数,您可以实现需要基于每条消息提供一组动态 URI 变量的方案。 以下示例显示了如何执行此操作:url-expressionspring-doc.cn

url-expression="T(org.springframework.web.util.UriComponentsBuilder)
                           .fromHttpUrl('https://HOST:PORT/PATH')
                           .queryParams(payload)
                           .build()
                           .toUri()"

该方法需要 a 作为参数,因此您可以在执行请求之前提前构建一组真实的 URL 查询参数。queryParams()MultiValueMap<String, String>spring-doc.cn

整体也可以表示为 ,如下例所示:queryStringuri-variablespring-doc.cn

<int-http:outbound-gateway id="proxyGateway" request-channel="testChannel"
              url="http://testServer/test?{queryString}">
    <int-http:uri-variable name="queryString" expression="'a=A&amp;b=B'"/>
</int-http:outbound-gateway>

在这种情况下,您必须手动提供 URL 编码。 例如,您可以使用 for this purpose. 如前所述,可以使用以下 Java Streams 代码段将手动构建的参数转换为 method 参数:org.apache.http.client.utils.URLEncodedUtils#format()MultiValueMap<String, String>List<NameValuePair>format()spring-doc.cn

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)的情况下,不需要执行编码。 的 and 提供了一个属性。 要禁用 URL 编码,请将此属性设置为 (默认情况下为 )。 如果您希望对 URL 的某些部分进行部分编码,请在 中使用 an,如下例所示:<http:outbound-gateway/><http:outbound-channel-adapter/>encoding-modeNONETEMPLATE_AND_VALUESexpression<uri-variable/>spring-doc.cn

<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()UriTemplateHandlerRestTemplateWebClientUriBuilderFactoryspring-doc.cn