当前位置: 首页 > 知识库问答 >
问题:

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

董建茗
2023-03-14

我试图实现某种代理作为我的数据流的一部分,我想在我的入站网关上接收超文本传输协议请求,并通过出站网关传递它。我想保留所有查询字符串参数。我的网关配置是:

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

我预计它的工作如下:

>

GET/services/normalization q=cat

入站网关接收请求,并将其通过搜索请求通道发送到出站网关。

出站网关向外部服务发送整个请求:

获取/查询q=cat

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

GET /query

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

共有2个答案

漆雕安晏
2023-03-14

我自己的解决方案是使用一个转换器将消息负载中的参数(查询字符串参数的映射)转换为准备好的查询字符串,并在出站网关中使用url-表达式来避免查询字符串编码:

<bean id="payloadToQueryString" 
    class="com.dph.integration.PayloadToQueryStringTransformer" />

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

<int:transformer input-channel="searchRequestChannel" 
     output-channel="searchGatewayChannel" 
     ref="payloadToQueryString" method="transform" />

<int-http:outbound-gateway id="searchServiceGateway"
    http-method="GET"
    request-channel="searchGatewayChannel"
    url-expression="'http://localhost:8080/query?' + payload"
    expected-response-type="java.lang.String"
    reply-timeout="50000"
    charset="UTF-8">
</int-http:outbound-gateway>

PayloadToQueryStringTransformer类别为:

public class PayloadToQueryStringTransformer extends AbstractTransformer {

@Override
protected Object doTransform(final Message<?> message) throws Exception {
    return MessageBuilder
        .withPayload(urlEncodeUTF8(((MultiValueMap) message.getPayload()).toSingleValueMap()))
        .copyHeaders(message.getHeaders())
        .build();
}

private static String urlEncodeUTF8(final String s) {
    try {
        return URLEncoder.encode(s, "UTF-8");
    } catch (final UnsupportedEncodingException e) {
        throw new UnsupportedOperationException(e);
    }
}
private static String urlEncodeUTF8(final Map<?,?> map) {
    final StringBuilder sb = new StringBuilder();
    for (final Map.Entry<?,?> entry : map.entrySet()) {
        if (sb.length() > 0) {
            sb.append("&");
        }
        sb.append(String.format("%s=%s",
                urlEncodeUTF8(entry.getKey().toString()),
                urlEncodeUTF8(entry.getValue().toString())
                ));
    }
    return sb.toString();
}

}
马涵蓄
2023-03-14

这是一个有点混乱,但工作;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>

然后在出站端,使用

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

但是,这在2.2中不起作用。因为查询字符串是在出站端编码的(foo=bar)

编辑:

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

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

在入站端,如果我们将queryString作为第一类表达式变量#queryString提供,则会更好。

请随时打开“改进”JIRA问题

 类似资料:
  • 我尝试使用以下代码,得到了回应:状态:405方法不允许。这是我的Http请求:http://localhost:8090/services/test?name=test.代码或http请求有什么问题?

  • 我不熟悉Spring集成。我正在尝试使用http入站网关构建一个简单的应用程序。下面是我得到的运行时异常。 下面是代码文件。 波约 服务 } 服务激活器 } 存储库 请帮助我,我正在试图找到异常发生的原因,但无法解决。提前谢谢。 集成文件。

  • 我正在尝试将spring集成配置为向队列发送消息,然后接收消息,即非常简单的事情: 我认为解耦所必需的是在流程的两端都有一个消息网关。因此,我的第一次尝试(有效)如下所示: 其中MessageReceiverHandler()是扩展AbstractMessageHandler的bean。 所以上面我们有一个用于出站消息的消息网关。我假设我们也应该有一个用于入站消息的网关,允许我们将传入消息处理与应

  • 我有一个http出站网关,它将json消息发布到rest服务,现在rest将以json消息类型的http错误状态响应,以防我们的应用程序捕获任何错误。在将json消息发布到rest服务并获得http成功状态的愉快场景中,我们的应用程序也应该捕获json消息。 现在我通过Spring集成实现了什么,我能够发送消息并获得成功响应并捕获它,但在错误状态下Spring行为会抛出异常,我如何更改行为? 如果

  • 我有一个 FileUpload 事件,应该将其发送到 http:outbound upload URL。为此,我必须首先对登录 URL 进行身份验证并获取响应,并设置要执行的出站上传 URL 的会话 ID。在我的情况下,我有一个事件侦听器,它侦听应用程序以发布文件上传事件。发布后,我的侦听器可以拾取并执行流。我正在尝试了解如何实现这一点,因为文件上传对象需要保留,直到登录响应返回。谢谢!

  • 我正在开发一个关于Spring集成的POC,使用如下。 从远程JMS队列订阅输入消息(A) 将输入消息(A)转换为(B) 使用(B)调用远程Web服务并接收响应 我的spring int-config-xml有以下内容 在我的Spring集成proj工作区中拥有所有jaxb生成的源代码。 在STS 3.8中执行此操作时。3,将抛出以下错误。 不确定我的代码中有什么错误。任何解决这一问题的帮助都是高