package link.at17.mid.tushare.component; import java.net.Proxy; import java.security.KeyStore; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.function.Consumer; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import link.at17.mid.tushare.system.config.SystemConfig; import link.at17.mid.tushare.system.util.SpringContextHolder; import okhttp3.OkHttpClient; /** * OkHttpClient 提供器 * @see link.at17.mid.tushare.system.config.SystemConfig * @see okhttp3.internal.http.BridgeInterceptor */ public class OkHttpClientProvider { private static volatile SystemConfig systemConfig; private static SystemConfig getSystemConfig() { if (systemConfig == null) { synchronized (OkHttpClientProvider.class) { if (systemConfig == null) { systemConfig = SpringContextHolder.getBean(SystemConfig.class); } } } return systemConfig; } /** * 根据 SystemConfig 获取一个 OkHttpClient 实例 * @return */ public static OkHttpClient getInstance() { return getInstance(null); } /** * 根据 SystemConfig 获取一个 OkHttpClient 实例 * @param builderConsumer 可根据该 consumer 自定义 builder 其他参数,注意 proxy、https 校验等最终仍会根据 systemConfig 情况覆盖 * @return */ public static OkHttpClient getInstance(Consumer builderConsumer) { SystemConfig systemConfig = getSystemConfig(); return getInstance( systemConfig.getProxy(), systemConfig.getIgnoreHttpsVerification(), builderConsumer); } /** * 根据指定代理和是否忽略 https 证书获取一个 OkHttpClient 实例 * @param proxy 指定代理 * @param ignoreHttpsVerification 是否忽略 https 证书 * @return */ public static OkHttpClient getInstance(Proxy proxy, boolean ignoreHttpsVerification) { return getInstance(proxy, ignoreHttpsVerification, null); } /** * 根据指定代理、是否忽略 https 证书和额外 builder 设置获取一个 OkHttpClient 实例 * @param proxy 指定代理 * @param ignoreHttpsVerification 是否忽略 https 证书 * @param builderConsumer 可根据该 consumer 自定义 builder 其他参数,注意 proxy、https 校验等最终仍会根据其他参数覆盖 * @return */ public static OkHttpClient getInstance( Proxy proxy, boolean ignoreHttpsVerification, Consumer builderConsumer) { OkHttpClient.Builder builder = new OkHttpClient.Builder(); if (builderConsumer != null) { builderConsumer.accept(builder); } builder.proxy(proxy); if (ignoreHttpsVerification) { builder .sslSocketFactory(getSSLSocketFactory(), getX509TrustManager()) .hostnameVerifier(getHostnameVerifier()); } return builder.build(); } private static HostnameVerifier getHostnameVerifier() { HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { return true; } }; return hostnameVerifier; } private static SSLSocketFactory getSSLSocketFactory() { try { SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, getTrustManager(), new SecureRandom()); return sslContext.getSocketFactory(); } catch (Exception e) { throw new RuntimeException(e); } } private static X509TrustManager getX509TrustManager() { X509TrustManager trustManager = null; try { TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init((KeyStore) null); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers)); } trustManager = (X509TrustManager) trustManagers[0]; } catch (Exception e) { e.printStackTrace(); } return trustManager; } private static TrustManager[] getTrustManager() { TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {} @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } } }; return trustAllCerts; } }