2013-05-07 18 views
5

Próbuję zaimplementować jakieś proxy jako część mojego przepływu danych, chcę otrzymać żądanie http na moją bramkę przychodzącą i przekazać ją przez bramkę wychodzącą . Chcę zachować wszystkie parametry ciągu zapytania. Moja konfiguracja bramki jest:Wiosenna integracja, w jaki sposób mogę przekazywać przychodzące żądania http za pośrednictwem bramy poczty wychodzącej?

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

Spodziewałem się, że będzie działać w następujący sposób:

  • Client wysłać swoją prośbę do bramy przychodzącej /usługi/normalizacji:

    get/Usługi/normalizacja q = cat & exclude = czarny

  • Brama poczty przychodzącej odbiera żądanie i wyślij go przez searchRequestChannel do bramy wychodzącej.

  • wychodząca bramka wysyła całe żądanie do usługi zewnętrznej:

    GET/zapytania q = kot & wykluczyć = czarny

Ale w praktyce, bramy wychodzące wysyła pusty wniosek, który nie zawiera jakiekolwiek Tak więc moje pytanie, jaki jest najłatwiejszy sposób wysłania żądania http, które zostało zaakceptowane w przychodzącym zbiorze danych przez bramkę wychodzącą. Innymi słowy, w jaki sposób mogę zaimplementować proste proxy za pomocą narzędzi do integracji wiosennej?

Odpowiedz

4

To trochę kludge, ale działa; DispatcherServlet wiąże żądanie do wątku ...

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

a następnie po stronie wychodzącej, należy

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

Jednak to nie będzie działać z 2.2.x, a wcześniej, bo w ciągu kwerendy jest zakodowany na stronie wychodzącej (foo=bar&baz=qux staje się foo%3Dbar%26baz%3Dqux). W wersji 3.0 dodaliśmy możliwość nie kodowania URI za pomocą atrybutu przy użyciu encode-uri="false". To nie jest jeszcze dostępne w wersji, ale jest dostępne pod numerem 3.0.0.BUILD-SNAPSHOT.

EDIT:

Powyższe ogólne rozwiązanie, które będzie pracować dla wszystkich ciągów zapytań; jeśli wiesz rzeczywiste parametry, innym rozwiązaniem byłoby wyodrębnić każdego parametru oddzielnie i odbudować ciąg kwerendy po stronie wychodzącej ...

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

Na stronie przychodzącej, byłoby lepiej, gdybyśmy oferowane ciągu kwerendy jako pierwsza klasa wyrażenia zmienna #queryString.

Prosimy otworzyć 'Improvement' JIRA Issue

+0

Hmm. Może robię coś złego, ale nagłówek queryString w odebranej wiadomości jest pusty. Sprawdziłem obiekt komunikatu w debugerze przy pomocy metody HttpRequestExecutingMessageHandler.handleRequestMessage (Message ). I mój wyjściowy rejestrator https://gist.github.com/detsam/5538976 – masted

+0

Przepraszam - mój błąd - przetestowałem go z fałszywym HttpRequest; pozwól mi zobaczyć, czy uda mi się wymyślić kolejną pracę. –

+0

Zaktualizowałem swoją odpowiedź, stosując ogólne rozwiązanie, które wymaga Spring Integration 3.0, i inne rozwiązanie, które zadziała, jeśli znasz parametry zapytania. –

4

Moje własne rozwiązanie Rozwiązaniem jest użycie transformator która przemienia parametrów ładunku wiadomości (mapa parametrów ciąg kwerendy) do przygotowanego string zapytanie i używać url ekspresja w wyjazdowej bramce uniknąć kodowanie ciąg kwerendy:

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

Klasa PayloadToQueryStringTransformer to:

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(); 
} 

} 
Powiązane problemy