@Configuration
public class RestTemplateConfig {
  //private static final LoggerLOGGER logger = XXXX 自己定義一個
  private static final intCONNECT_TIMEOUT= 10 * 1000;
  private static final intREQUEST_TIMEOUT= 30 * 1000;
  private static final intSOCKET_TIMEOUT= 60 * 1000;
  private static final intMAX_TOTAL_CONNECTIONS= 100;
  private static final intDEFAULT_THREAD_POOL_SIZE= 50;
  private static final intCLOSE_IDLE_CONNECTION_WAIT_TIME_SECS= 60;
  private static final intSCHEDULER_FIXED_DELAY_IN_MILLI_SECS= 600000;
  @Bean(name="httpTeamplateClient")
  public HttpClient httpTemplateClient() {
    return HttpClientBuilder.create().build();
  }
  @Bean
  public RestTemplate restTemplate(@Qualifier("requestFactory") ClientHttpRequestFactory httpRequestFactory) {
    RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
    return restTemplate;
  }
  @Bean (name="requestFactory")
  public ClientHttpRequestFactory httpRequestFactory(@Qualifier("poolingConnectionManager") PoolingHttpClientConnectionManager poolingHttpClientConnectionManager,
                                                     @Qualifier("closeableHttpClient") CloseableHttpClient httpClient) {
    return new HttpComponentsClientHttpRequestFactory(httpClient);
  }
  @Bean (name="closeableHttpClient")
  public CloseableHttpClient httpClient() throws NoSuchAlgorithmException, KeyManagementException {
    TrustManager[] trustAllCerts = getTrustManager();
    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(null, trustAllCerts, new SecureRandom());
    RequestConfig.Builder requestConfig = RequestConfig.custom();
    if (StringUtils.isNotBlank(proxyHost) && StringUtils.isNotBlank(proxyPort)) {
      HttpHost proxy = new HttpHost(proxyHost, Integer.parseInt(proxyPort), "http");
      requestConfig.setProxy(proxy);
    }
    requestConfig
      .setConnectionRequestTimeout(REQUEST_TIMEOUT)
      .setConnectTimeout(CONNECT_TIMEOUT)
      .setSocketTimeout(SOCKET_TIMEOUT);
    return HttpClientBuilder.create()
      .setDefaultRequestConfig(requestConfig.build())
      .setConnectionManager(poolingConnectionManager())
      .build();
  }
  @Bean
  public TaskScheduler taskScheduler() {
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    scheduler.setThreadNamePrefix("poolScheduler-config");
    scheduler.setPoolSize(DEFAULT_THREAD_POOL_SIZE);
    return scheduler;
  }
  @Bean (name="poolingConnectionManager")
  public PoolingHttpClientConnectionManager poolingConnectionManager() {
    Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
      .register("http", PlainConnectionSocketFactory.getSocketFactory())
      .register("https", SSLConnectionSocketFactory.getSocketFactory())
      .build();
    PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(registry);
    poolingConnectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
    return poolingConnectionManager;
  }
  @Bean
  public Runnable idleConnectionMonitor(final PoolingHttpClientConnectionManager connectionManager) {
    return new Runnable() {
      @Override
      @Scheduled(fixedDelay =SCHEDULER_FIXED_DELAY_IN_MILLI_SECS)
      public void run() {
        try {
          if (connectionManager != null) {
LOGGER.info("run IdleConnectionMonitor - Closing expired and idle connections...");
            connectionManager.closeExpiredConnections();
            connectionManager.closeIdleConnections(CLOSE_IDLE_CONNECTION_WAIT_TIME_SECS, TimeUnit.SECONDS);
          } else {
LOGGER.info("run IdleConnectionMonitor - Http Client Connection manager is not initialised");
          }
        } catch (Exception e) {
LOGGER.error("run IdleConnectionMonitor - Exception occurred. msg={}, e={}", e.getMessage(), e);
        }
      }
    };
  }
// 繞開證書
  private TrustManager[]  getTrustManager(){
    return new TrustManager[] {
      new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() {
          return new X509Certificate[0];
        }
        public void checkClientTrusted(
          X509Certificate[] certs, String authType) {
        }
        public void checkServerTrusted(
          X509Certificate[] certs, String authType) {
        }
      }
    };
  }
}

# Reference

  1. HttpClient 连接池的实现
  2. X509TrustManager 信任 SSL 证书
  3. Java 安全通信:HTTPS 与 SSL