okhttp3访问https出现CertPathValidato

2017-07-12  本文已影响686人  这种事你也信以为真

这个错误折腾了我两天了,实在是印象深刻,不记一下都觉得对不起自己这两天的折磨。首先,描述一下问题。
问题:一开始我用的是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);
    }

嗯,删删改改到此为止,我已经说服不了自己为什么了,但是问题应该是出现这边,如果有错的话,或者有解答的话,咱评论区见~
好了,这次错误就记录到这边了,我自己反省蹲墙角去了,再见,筒子们!

上一篇下一篇

猜你喜欢

热点阅读