У динамических URL-адресов https исходящего шлюза Spring интеграции есть проблема - PullRequest
0 голосов
/ 06 декабря 2018

Я хочу создать мягкий шлюз, поэтому я предоставлю своей внутренней системе URL-адрес весенней интеграции, а затем моя система отправит URL-адрес реального места назначения.вот мой кодЭто исходящий шлюз, и я установил https url в заголовках входного канала.

<int:channel id="inputChannel"/>
<int:channel id="outputChannel">
    <int:queue capacity="100"/>
</int:channel>

<int-http:outbound-gateway   request-channel="inputChannel"
                            url-expression="headers.dynamicUrl"
                           http-method-expression="POST"
                           expected-response-type="java.lang.String"
                            reply-channel="outputChannel"

                           charset="UTF-8">
</int-http:outbound-gateway>

, и мой код Java такой:

MessageChannel inputChannel = context.getBean("inputChannel", MessageChannel.class);
    PollableChannel outputChannel = context.getBean("outputChannel", PollableChannel.class);
    inputChannel.send(msgWithHTTPsUrl);//msg with https Url https://www.example.net
    Message<?> replyMesg = outputChannel.receive();
    Message<?> toSend = MessageBuilder.withPayload(replyMesg.getPayload()).copyHeadersIfAbsent(replyMesg.getHeaders()).build();
    System.out.println(toSend);
    return toSend;

, и программа может печатать, чтобы отправить сообщение.но браузер не может получить ответ. Это говорит ERR_CONTENT_DECODING_FAILED.Возможно, https://www.example.net использует сжатие gzip.Итак, как мне справиться с этим, чтобы я мог сделать мягкий шлюз для внутренней системы моей компании?спасибо!


Теперь я добавляю шаблон отдыха для решения этой ошибки

<int-http:outbound-gateway   request-channel="inputChannel"
                        url-expression="headers.dynamicUrl"
                       http-method-expression="POST"
                       expected-response-type="java.lang.String"
                        reply-channel="outputChannel"
                        rest-template="restTemplate"
                       charset="UTF-8">

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
    <constructor-arg ref="sslFactory" />
</bean>
<bean id="sslFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
    <constructor-arg ref="httpClient"/>
</bean>

, и я установил игнорирование проверки сервера-боковые сертификаты. Вот мой java-код httpclient

        @Component("httpClient")
    public class HttpClientFactory extends AbstractFactoryBean<HttpClient> {

        @Override
        public Class<?> getObjectType() {
            return HttpClient.class;
        }
        public HttpClient getInstance() throws Exception {
            return createInstance();
        }
        @Override
        protected HttpClient createInstance() throws Exception {

            RequestConfig defaultRequestConfig = RequestConfig.custom()
                    .setSocketTimeout(3000)
                    .setConnectTimeout(3000)
                    .setConnectionRequestTimeout(3000)
                    .setStaleConnectionCheckEnabled(true)
                    .build();

            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            TrustStrategy allTrust = new TrustStrategy() {
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            };

            SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, allTrust).build();

            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
                    .setDefaultRequestConfig(defaultRequestConfig).build();
            return httpClient;
        }

, но outbund-gateway получает ответ 4xx / 5xx, когда я использую этот httpclient, и я пишу HttpPost для проверки этого httpclient, с ответом все в порядке.Что-то я не так понимаю из-за outbund-gateway?Или что еще я пропустил?


Я пишу контрольный пример для тестирования моего приложения весенней интеграции и httpclient, который я добавляю в интеграцию Spring.приложение весенней интеграции получает ответ об ошибке:

org.springframework.messaging.MessageHandlingException: HTTP request execution failed for URI [https://www.npr.org/]; nested exception is org.springframework.web.client.HttpClientErrorException: 400 Bad Request, failedMessage=GenericMessage [payload=byte[0], headers={content-length=0, http_requestMethod=POST, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@3afa4833, httpMethod=POST, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@3afa4833, respUrl=https://www.npr.org/, host=localhost:8080, http_requestUrl=http://localhost:8080/sihttp/mytest, connection=Keep-Alive, id=256ed96e-9c00-ecf4-9d1b-63f37635fb4a, contentType=application/json;charset=UTF-8, accept-encoding=gzip,deflate, user-agent=Apache-HttpClient/4.5.6 (Java/1.8.0_131), timestamp=1544368429831}]

, и посещение httpClient https://www.npr.org/ напрямую приводит к успешному возвращению.Тестовый код выглядит следующим образом:

CloseableHttpClient httpClient = HttpClients.createDefault(); // same httpclinet I inject in outbound gateway's rest-template
    HttpPost post=null;
    post = new HttpPost("http://localhost:8080/sihttp/mytest"); // this post will goto my spring integration app, in spring integration app, I will map this  url to https://www.npr.ogr, and send out in outbound gateway
//   post = new HttpPost("https://www.npr.org/"); // npr.org can successful visit in this post
        post.setHeader("Content-Type", "application/json;charset=UTF-8");
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(6000).setConnectionRequestTimeout(6000)
                .setSocketTimeout(6000).build();
        post.setConfig(requestConfig);
        CloseableHttpResponse httpResponse = httpClient.execute(post);
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            System.out.println(EntityUtils.toString(httpEntity));
        }

        httpResponse.close();

в весенней интеграции httpclient выполняется с httpContext

HttpResponse httpResponse = this.httpClient.execute(this.httpRequest, this.httpContext);

, а в HttpClient выполняется напрямую.

httpClient.execute(post);

Это причина двух разных результатов?

1 Ответ

0 голосов
/ 06 декабря 2018

Если история о GZIP, вам следует рассмотреть возможность введения в <int-http:outbound-gateway> другого:

<xsd:attribute name="request-factory" type="xsd:string">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
Reference to a ClientHttpRequestFactory to be used by the underlying RestTemplate.
                ]]></xsd:documentation>
            <xsd:appinfo>
                <tool:annotation kind="ref">
                    <tool:expected-type type="org.springframework.http.client.ClientHttpRequestFactory" />
                </tool:annotation>
            </xsd:appinfo>
        </xsd:annotation>
    </xsd:attribute>

Я рекомендую использовать HttpComponentsClientHttpRequestFactory.

Если дажеэто не поможет, пожалуйста, поделитесь с нами всей трассировкой стека, чтобы определить, что может быть пропущено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...