这个错误折腾了我两天了,实在是印象深刻,不记一下都觉得对不起自己这两天的折磨。首先,描述一下问题。
问题:一开始我用的是okhttp2.7.4,访问https接口正常,后来因为项目需要,切换到了okhttp3.4.1,然后改改改,作死的来了,改完发现,访问https接口会报CertPathValidatorException:Trust anchor for certification path not found。我就郁闷了,各种百度,各种想可能出现问题的点。后来,几乎都放弃了要用回2.7.4版本了。最后终于给我找到原因了,好气好气哦!
原因:2.x版本的设置okhhtp相关参数是这样子设置的:
mOkHttpClient = new OkHttpClient();
mOkHttpClient.setConnectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS);
mOkHttpClient.setReadTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS);
mOkHttpClient.setWriteTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS);
setCertificates();
// cookie enabled
mOkHttpClient.setCookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER));
切换到3.x以后我修改的代码是酱婶的:
mOkHttpClient = new OkHttpClient();
OkHttpClient.Builder builder = mOkHttpClient.newBuilder();
builder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
.readTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
.sslSocketFactory(setCertificates())
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
})
.cookieJar(new CookieJar() {
private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url, cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url);
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();
是不是觉得老铁没毛病啊,是的,一开始我也是对这段代码深信不疑。后来,事实给了阿爹一巴掌 。T_T
正确的写法是:
mOkHttpClient = new OkHttpClient.Builder()
.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
.readTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
.sslSocketFactory(setCertificates())
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
})
.cookieJar(new CookieJar() {
private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url, cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url);
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();
可能有人想问,有区别吗?我去瞅了下源码,还真特么有区别!
mOkHttpClient = new OkHttpClient();
OkHttpClient.Builder builder = mOkHttpClient.newBuilder();
当第一次去new OkHttpClient()的时候
public OkHttpClient() {
this(new OkHttpClient.Builder());
}
源码做了这个,然而Builder是OkHttpClient的静态final的内部类,所以,下面一行mOkHttpClient.newBuilder(),源码又来了这么一段
public OkHttpClient.Builder newBuilder() {
return new OkHttpClient.Builder(this);
}
嗯,删删改改到此为止,我已经说服不了自己为什么了,但是问题应该是出现这边,如果有错的话,或者有解答的话,咱评论区见~
好了,这次错误就记录到这边了,我自己反省蹲墙角去了,再见,筒子们!