2013-05-07 42 views
5

我試圖實現某種代理作爲我的數據流的一部分,我想接收一個http請求我的入站網關,並通過出站網關傳遞它。我想保留所有查詢字符串參數。我的網關的配置是:Spring集成,我怎麼能穿過站網關入站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" 
/> 

我預計它會工作如下:

  • 客戶端發送請求到入站網關/服務/正常化

    GET /服務/歸一化q =貓&排除=黑

  • 入站網關接收請求和searchRequestChannel發送通過出站網關。

  • 出站網關發送整個請求到外部服務:

    GET /查詢q =貓&排除=黑色

但在實踐中,出站網關發送一個不包含任何空請求查詢參數:

GET /query 

所以我的問題,什麼是送這是對入境gatew接受http請求最簡單的方法通過出站網關。換句話說,我如何通過彈簧集成工具實現簡單代理?

回答

4

這是一個有點雜牌的,但工程;該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.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> 

在入境方面,它會更好,如果我們提供的查詢字符串作爲第一類表達變量#queryString

請隨意打開一個'Improvement' JIRA Issue

+0

嗯。也許我做錯了,但收到的消息中的'queryString'頭是空的。我用HttpRequestExecutingMessageHandler.handleRequestMessage(Message )方法在調試器中檢查了消息對象。和我的記錄器輸出https://gist.github.com/detsam/5538976 – masted 2013-05-08 08:15:23

+0

對不起 - 我的錯誤 - 我用模擬HttpRequest測試它;讓我看看我是否可以提出另一項解決方案。 – 2013-05-08 13:03:39

+0

我用一個需要Spring Integration 3.0的通用解決方案更新了我的答案,如果知道查詢參數,另一個解決方案將工作。 – 2013-05-08 15:08:04

4

我自己的解決方法解決方案是使用變壓器,在消息負載轉換參數(地圖查詢字符串參數),以備查詢字符串和使用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(); 
} 

} 
相關問題