OkHttp3 + https 的坑
今天使用glide +https, 参照glide wiki 的代码噌噌噌编好了,一试发现怎么地都不行,一步一步追踪发现问题出在Okhttp的https设置上,
各种比对之前的代码发现都没问题。。。直到重新试了另一种代码方式才发现问题最终出现的地方。
1.glide wiki里的unsafeHttpClient代码如下:
public class UnsafeOkHttpClient { public static OkHttpClient getUnsafeOkHttpClient() { try { // Create a trust manager that does not validate certificate chains final TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } } }; // Install the all-trusting trust manager final SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); // Create an ssl socket factory with our all-trusting manager final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setSslSocketFactory(sslSocketFactory); okHttpClient.setProtocols(Arrays.asList(Protocol.HTTP_1_1)); okHttpClient.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); return okHttpClient; } catch (Exception e) { throw new RuntimeException(e); } } }
因为这个OKhttp的版本比较早,换成最新的代码如下(姑且称之为代码2):
public class UnsafeOkHttpClient { public static OkHttpClient getUnsafeOkHttpClient() throws KeyManagementException, NoSuchAlgorithmException { try { // Create a trust manager that does not validate certificate chains final TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } } }; // Install the all-trusting trust manager final SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); // Create an ssl socket factory with our all-trusting manager final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslSocketFactory); builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); return builder.build(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } }
如果只是这么替换一下,nice,坑出现了。。。。。
问题出在,builder.sslSocketFactory(sslSocketFactory); 这一行,目前的版本,这一行会抛出空指针异常,而事实上,抛出异常并不影响使用。
所以,只要换成一下代码即可得到正常效果了。
public class UnsafeOkHttpClient { public static OkHttpClient getUnsafeOkHttpClient() { // Create a trust manager that does not validate certificate chains final TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } } }; // Install the all-trusting trust manager SSLContext sslContext = null; try { sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new SecureRandom()); } catch (Exception e) { e.printStackTrace(); } // Create an ssl socket factory with our all-trusting manager final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslSocketFactory); builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); return builder.build(); } }
注意 try catch的位置。。。。。
就酱。。