All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dahua.eco.base.spring.http.RestTemplateConfig Maven / Gradle / Ivy

package com.dahua.eco.base.spring.http;

import com.dahua.eco.base.spring.config.RestTemplateProperties;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpResponse;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;

@Component
public class RestTemplateConfig {
    private static Logger logger = LoggerFactory.getLogger(RestTemplateConfig.class);

    @Autowired
    private RestTemplateProperties restTemplateProperties;

    private static final int HTTP_CLIENT_RETRY_COUNT = 3;
    /**
     * @Title: restTemplate
     * @Description: 普通HTTP RestTemplate
     * @param @return    设定文件
     * @return RestTemplate    返回类型
     * @throws
     */
    @Bean
    public RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory restFactory = new SimpleClientHttpRequestFactory();
        // 设置restTemplate接口连接和获取数据最大连接时间
        restFactory.setReadTimeout(restTemplateProperties.getReadTimeout());
        restFactory.setConnectTimeout(restTemplateProperties.getConnectTimeout());
        restFactory.setBufferRequestBody(false);
        RestTemplate restTemplate = new RestTemplate(restFactory);
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        restTemplate.getMessageConverters().add(converter);
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
        return restTemplate;
    }

    /**
     * @Title: restHttpsTemplate
     * @Description: HTTPS  RestTemplate
     * @param @return
     * @param @throws KeyStoreException
     * @param @throws NoSuchAlgorithmException
     * @param @throws KeyManagementException    设定文件
     * @return RestTemplate    返回类型
     * @throws
     */
    @Bean
    public RestTemplate restHttpsTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        CloseableHttpClient httpClient = null;
        try {
            httpClient = acceptsUntrustedCertsHttpClient();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        HttpComponentsClientHttpRequestFactory restFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        // 设置restTemplate接口连接和获取数据最大连接时间
        restFactory.setReadTimeout(restTemplateProperties.getReadTimeout());
        restFactory.setConnectTimeout(restTemplateProperties.getConnectTimeout());
        restFactory.setBufferRequestBody(false);
        RestTemplate restTemplate = new RestTemplate(restFactory);
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        restTemplate.getMessageConverters().add(converter);
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
        return restTemplate;
    }


    /**
     * 加入所有信任证书
     *
     * @return
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    private CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        HttpClientBuilder b = HttpClientBuilder.create();
        //在握手期间,如果URL的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口的实现   程序来确定是否应该允许此连接
        HostnameVerifier hv = new HostnameVerifier() {
            @Override
            public boolean verify(String urlHostName, SSLSession session) {
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);

        // setup a Trust Strategy that allows all certificates.
        //
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                return true;
            }
        }).build();
        b.setSSLContext(sslContext);

        // don't check Hostnames, either.
        //      -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
        HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;

        // here's the special part:
        //      -- need to create an SSL Socket Factory, to use our weakened "trust strategy";
        //      -- and create a Registry, to register it.
        //
        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
        Registry socketFactoryRegistry = RegistryBuilder.create()
//                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", sslSocketFactory)
                .build();

        // now, we create connection-manager using our Registry.
        //      -- allows multi-threaded use
        PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        connMgr.setMaxTotal(500);
        connMgr.setDefaultMaxPerRoute(100);
        b.setConnectionManager(connMgr);
        b.setRetryHandler(new DefaultHttpRequestRetryHandler(restTemplateProperties.getRetryCount(), true, new ArrayList<>()) {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                logger.info("Retry request, execution count: {}, execution message: {}", executionCount, exception.getMessage());
                logger.debug("Retry request, exception: {}", exception);
                return super.retryRequest(exception, executionCount, context);
            }
        });
        b.setKeepAliveStrategy(defaultStrategy);


//        b.setRetryHandler(new DefaultHttpRequestRetryHandler());

        // finally, build the HttpClient;
        //      -- done!
        CloseableHttpClient client = b.build();

        return client;
    }

    /**
     * Http connection keepAlive 设置
     */
    public static ConnectionKeepAliveStrategy defaultStrategy = new ConnectionKeepAliveStrategy() {

        public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
            HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
            while (it.hasNext()) {

                final HeaderElement he = it.nextElement();
                final String param = he.getName();
                final String value = he.getValue();
                if (value != null && param.equalsIgnoreCase("timeout")) {
                    try {
                        return Long.parseLong(value) * 1000;
                    } catch(final NumberFormatException ignore) {
                        logger.error("ConnectionKeepAliveStrategy format KeepAlive timeout exception, exception:" + ignore.getMessage(), ignore);
                    }
                }

            }
            return -1;
        }
    };
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy