How to use Apache CachingHttpAsyncClient with Spring AsyncRestTemplate?

五迷三道 提交于 2019-12-12 05:28:21

问题


Is it possible to use CachingHttpAsyncClient with AsyncRestTemplate? HttpComponentsAsyncClientHttpRequestFactory expects a CloseableHttpAsyncClient but CachingHttpAsyncClient does not extend it.


回答1:


This is known as issue SPR-15664 for versions up to 4.3.9 and 5.0.RC2 - fixed in 4.3.10 and 5.0.RC3. The only way around is is creating a custom AsyncClientHttpRequestFactory implementation that is based on the existing HttpComponentsAsyncClientHttpRequestFactory:

// package required for HttpComponentsAsyncClientHttpRequest visibility
package org.springframework.http.client;

import java.io.IOException;
import java.net.URI;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.Configurable;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.cache.CacheConfig;
import org.apache.http.impl.client.cache.CachingHttpAsyncClient;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.protocol.HttpContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.HttpMethod;
import org.springframework.util.Assert;

// TODO add support for other CachingHttpAsyncClient otpions, e.g. HttpCacheStorage
public class HttpComponentsCachingAsyncClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory implements AsyncClientHttpRequestFactory, InitializingBean {

    private final CloseableHttpAsyncClient wrappedHttpAsyncClient;
    private final CachingHttpAsyncClient cachingHttpAsyncClient;

    public HttpComponentsCachingAsyncClientHttpRequestFactory() {
        this(HttpAsyncClients.createDefault(), CacheConfig.DEFAULT);
    }

    public HttpComponentsCachingAsyncClientHttpRequestFactory(final CacheConfig config) {
        this(HttpAsyncClients.createDefault(), config);
    }

    public HttpComponentsCachingAsyncClientHttpRequestFactory(final CloseableHttpAsyncClient client) {
        this(client, CacheConfig.DEFAULT);
    }

    public HttpComponentsCachingAsyncClientHttpRequestFactory(final CloseableHttpAsyncClient client, final CacheConfig config) {
        Assert.notNull(client, "HttpAsyncClient must not be null");
        wrappedHttpAsyncClient = client;
        cachingHttpAsyncClient = new CachingHttpAsyncClient(client, config);
    }

    @Override
    public void afterPropertiesSet() {
        startAsyncClient();
    }

    private void startAsyncClient() {
        if (!wrappedHttpAsyncClient.isRunning()) {
            wrappedHttpAsyncClient.start();
        }
    }

    @Override
    public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) throws IOException {
        throw new IllegalStateException("Synchronous execution not supported");
    }

    @Override
    public AsyncClientHttpRequest createAsyncRequest(final URI uri, final HttpMethod httpMethod) throws IOException {
        startAsyncClient();
        final HttpUriRequest httpRequest = createHttpUriRequest(httpMethod, uri);
        postProcessHttpRequest(httpRequest);
        HttpContext context = createHttpContext(httpMethod, uri);
        if (context == null) {
            context = HttpClientContext.create();
        }
        // Request configuration not set in the context
        if (context.getAttribute(HttpClientContext.REQUEST_CONFIG) == null) {
            // Use request configuration given by the user, when available
            RequestConfig config = null;
            if (httpRequest instanceof Configurable) {
                config = ((Configurable) httpRequest).getConfig();
            }
            if (config == null) {
                config = createRequestConfig(cachingHttpAsyncClient);
            }
            if (config != null) {
                context.setAttribute(HttpClientContext.REQUEST_CONFIG, config);
            }
        }
        return new HttpComponentsAsyncClientHttpRequest(cachingHttpAsyncClient, httpRequest, context);
    }

    @Override
    public void destroy() throws Exception {
        try {
            super.destroy();
        } finally {
            wrappedHttpAsyncClient.close();
        }
    }

}


来源:https://stackoverflow.com/questions/44539146/how-to-use-apache-cachinghttpasyncclient-with-spring-asyncresttemplate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!