RestTemplate HttpClient详解及如何设置忽略SSL

@Configuration
public class ScheduleRestConfigurer {
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory());

        FormHttpMessageConverter formConverter = new FormHttpMessageConverter();
        restTemplate.getMessageConverters().add(formConverter);
        restTemplate.getMessageConverters().add(new JacksonConverter());
        return restTemplate;
    }

    @Bean
    public ClientHttpRequestFactory httpRequestFactory() {
        return new HttpComponentsClientHttpRequestFactory(httpClient());
    }

    @Bean
    public HttpClient httpClient() {
        //设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", sslConnectionSocketFactory())
                .build();
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);

        int maxTotal = 100;
        int defaultMaxPerRoute = 20;
        int validateAfterInactivity = 10000;
        int socketTimeout = 30000;
        int connectTimeout = 30000;
        int connectionRequestTimeout = 30000;
        connectionManager.setMaxTotal(maxTotal); // 最大连接数
        connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);    //单个路由最大连接数
        connectionManager.setValidateAfterInactivity(validateAfterInactivity); // 最大空间时间

        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(socketTimeout)        //服务器返回数据(response)的时间,超过抛出read timeout
                .setConnectTimeout(connectTimeout)      //连接上服务器(握手成功)的时间,超出抛出connect timeout
                // .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled) // 提交前检测是否可用
                .setConnectionRequestTimeout(connectionRequestTimeout)//从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
                .build();

        return HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .setConnectionManagerShared(false)
                .evictIdleConnections(3000, TimeUnit.MILLISECONDS)
                //默认重试3次 会从连接池中获取 不会直接创建新的连接 此处不允许重试
                .disableAutomaticRetries()
                .build();
    }

    @Bean
    public SSLConnectionSocketFactory sslConnectionSocketFactory() {
        SSLConnectionSocketFactory sslsf;
        try {
            SSLContextBuilder builder = SSLContexts.custom();
            builder.loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) {
                    return true;
                }
            });

            SSLContext sslContext = builder.build();
            sslsf = new SSLConnectionSocketFactory(
                    sslContext, new X509HostnameVerifier() {
                @Override
                public void verify(String host, SSLSocket ssl)
                        throws IOException {
                }

                @Override
                public void verify(String host, X509Certificate cert)
                        throws SSLException {
                }

                @Override
                public void verify(String host, String[] cns,
                                   String[] subjectAlts) throws SSLException {
                }

                @Override
                public boolean verify(String s, SSLSession sslSession) {
                    return true;
                }
            });
            return sslsf;
        } catch (Exception e) {
            return null;
        }
    }

    public class JacksonConverter extends MappingJackson2HttpMessageConverter {
        public JacksonConverter(){
            List<MediaType> mediaTypes=new ArrayList<>();
            //添加text/html类型的支持
            mediaTypes.add(MediaType.TEXT_HTML);
            //添加text/plain类型的支持.微信接口会用到
            mediaTypes.add(MediaType.TEXT_PLAIN);
            setSupportedMediaTypes(mediaTypes);
        }
    }
}

 

posted @ 2021-01-21 19:39  牧之丨  阅读(1088)  评论(0编辑  收藏  举报