Spring Integration,如何通过出站网关传递入站http请求?

mas*_*ted 5 spring spring-integration

我正在尝试将某种代理实现为我的数据流的一部分,我希望在我的入站网关上接收http请求并通过出站网关传递它.我想保留所有查询字符串参数.我的网关配置是:

<int:channel id="searchRequestChannel" />
<int:channel id="searchReplyChannel" />

<int-http:inbound-gateway id="searchRequestInboundGateway"      
    supported-methods="GET" 
    request-channel="searchRequestChannel"
    reply-channel="searchReplyChannel"      
    path="/services/normalization"
    reply-timeout="50000"
/>

<int-http:outbound-gateway id="searchServiceGateway"
    http-method="GET"
    request-channel="searchRequestChannel"
    url="http://localhost:8080/query"
    extract-request-payload="false"
    expected-response-type="java.lang.String"
    reply-timeout="50000"
    charset="UTF-8"
/>
Run Code Online (Sandbox Code Playgroud)

我预计它将如下工作:

  • 客户端向入站网关/服务/规范化发送请求:

    GET /服务/标准化q = cat&exclude = black

  • 入站网关接收请求并通过searchRequestChannel将其发送出站网关.

  • 出站网关将整个请求发送到外部服务:

    GET /查询q = cat&exclude = black

但在实践中,出站网关发送不包含任何查询参数的空请求:

GET /query
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,通过出站网关发送入站网关接受的http请求的最简单方法是什么.换句话说,如何通过spring集成工具实现简单代理?

Gar*_*ell 5

这有点拼凑,但很有效;将DispatcherServlet请求绑定到线程...

<int-http:inbound-gateway id="searchRequestInboundGateway"      
    supported-methods="GET" 
    request-channel="searchRequestEnricherChannel"
    reply-channel="searchReplyChannel"      
    path="/services/normalization{queryString}"
    reply-timeout="50000"
/>

<int:header-enricher input-channel="searchRequestEnricherChannel" output-channel="searchRequestChannel">
    <int:header name="queryString" 
        expression="T(org.springframework.web.context.request.RequestContextHolder).requestAttributes.request.queryString" />
</int:header-enricher>
Run Code Online (Sandbox Code Playgroud)

然后在出站端,使用

<int-http:outbound-gateway id="searchServiceGateway"
    http-method="GET"
    request-channel="searchRequestChannel"
    url="http://localhost:8080/query?{queryString}"
    encode-uri="false"
    extract-request-payload="false"
    expected-response-type="java.lang.String"
    reply-timeout="50000"
    charset="UTF-8">
    <uri-variable name="queryString" expression="headers.queryString" />
</int-http:outbound-gateway>
Run Code Online (Sandbox Code Playgroud)

但是,这不适用于 2.2.x 及更早版本,因为查询字符串在出站端进行编码(foo=bar&baz=qux变为foo%3Dbar%26baz%3Dqux)。在 3.0 中,我们添加了不使用属性对 URI 进行编码的功能,方法是使用encode-uri="false". 此功能尚未在发行版中提供,但在3.0.0.BUILD-SNAPSHOT.

编辑:

以上是适用于所有查询字符串的通用解决方案;如果您知道实际参数,另一种解决方案是单独提取每个参数并在出站端重建查询字符串......

<int-http:inbound-gateway ... >
    <int-http:header name="foo" expression="#requestParams.foo.get(0)"/>                          
    <int-http:header name="baz" expression="#requestParams.baz.get(0)"/>
</int-http:inbound-gateway>

<int-http:outbound-gateway request-channel="requestChannel" 
                           url="http://localhost:18080/http/receiveGateway?foo={foo}&amp;baz={baz}"
                           http-method="POST"
                           expected-response-type="java.lang.String">
    <int-http:uri-variable name="foo" expression="headers.foo"/>
    <int-http:uri-variable name="baz" expression="headers.baz"/>
</int-http:outbound-gateway>
Run Code Online (Sandbox Code Playgroud)

在入站方面,如果我们提供 queryString 作为第一类表达式变量,那就更好了#queryString

请随时提出“改进”JIRA 问题