zoukankan      html  css  js  c++  java
  • Android使用Glide加载https链接的图片不显示的原因

    平时我们使用Glide加载http网址的图片的时候,图片可以正常加载出来,但是如果服务器端加上了安全认证,当加载自签名的https图片的时候就会报如下错误(证书路径验证异常)。 

    我们如果不修改Glide的代码的话,是会出现

    javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.这个异常,导致图片加载不出来。

    okhttp我们使用ssl来信任的所有证书,但是glide使用的自己的网络请求来加载的图片,也就是说,想要用glide访问https图片,就必须替换掉glide原始加载图片的方法,使其同样做到信任所有证书。

    所以需要修改Glide的OkHttpGlideModule.class  OkHttpStreamFetcher.class OkHttpUrlLoader.class这三个类,

    OkHttpGlideModule.java

    package com.example.androidtest.https;
    import android.content.Context;

    import com.bumptech.glide.Glide;
    import com.bumptech.glide.GlideBuilder;
    import com.bumptech.glide.load.model.GlideUrl;
    import com.bumptech.glide.module.GlideModule;
    import com.example.androidtest.SSLSocketClient;

    import java.io.InputStream;

    import okhttp3.OkHttpClient;

    public class OkHttpGlideModule implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
    OkHttpClient mHttpClient = new OkHttpClient().newBuilder()
    .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())
    .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
    .build();
    glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(mHttpClient));
    }
    }

    OkHttpStreamFetcher.java

    /**
    * <p>Title: OkHttpStreamFetcher.java</p>
    * <p>Description: </p>
    * <p>Copyright: Copyright (c) 2017</p>
    * <p>Company: www.baidudu.com</p>
    * @author tsj
    * @date 2018 10 18
    * @version 1.0
    */
    package com.example.androidtest.https;

    /**
    * <p>Title: OkHttpStreamFetcher</p>
    * <p>Description: </p>
    * @author tsj
    * @date 2018 10 18
    */
    import com.bumptech.glide.Priority;
    import com.bumptech.glide.load.data.DataFetcher;
    import com.bumptech.glide.load.model.GlideUrl;
    import com.bumptech.glide.util.ContentLengthInputStream;

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Map;

    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    import okhttp3.ResponseBody;

    public class OkHttpStreamFetcher implements DataFetcher<InputStream> {
    private final OkHttpClient client;
    private final GlideUrl url;
    private InputStream stream;
    private ResponseBody responseBody;

    public OkHttpStreamFetcher(OkHttpClient client, GlideUrl url) {
    this.client = client;
    this.url = url;
    }

    @Override
    public InputStream loadData(Priority priority) throws Exception {
    Request.Builder requestBuilder = new Request.Builder()
    .url(url.toStringUrl());

    for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) {
    String key = headerEntry.getKey();
    requestBuilder.addHeader(key, headerEntry.getValue());
    }

    Request request = requestBuilder.build();

    Response response = client.newCall(request).execute();
    responseBody = response.body();
    if (!response.isSuccessful()) {
    throw new IOException("Request failed with code: " + response.code());
    }

    long contentLength = responseBody.contentLength();
    stream = ContentLengthInputStream.obtain(responseBody.byteStream(), contentLength);
    return stream;
    }

    @Override
    public void cleanup() {
    if (stream != null) {
    try {
    stream.close();
    } catch (IOException e) {
    }
    }
    if (responseBody != null) {
    responseBody.close();
    }
    }

    @Override
    public String getId() {
    return url.getCacheKey();
    }

    @Override
    public void cancel() {
    }
    }

    OkHttpUrlLoader.java

    /**
    * <p>Title: OkHttpUrlLoader.java</p>
    * <p>Description: </p>
    * <p>Copyright: Copyright (c) 2017</p>
    * <p>Company: www.baidudu.com</p>
    * @author tsj
    * @date 2018 10 18
    * @version 1.0
    */
    package com.example.androidtest.https;

    import android.content.Context;

    import com.bumptech.glide.load.data.DataFetcher;
    import com.bumptech.glide.load.model.GenericLoaderFactory;
    import com.bumptech.glide.load.model.GlideUrl;
    import com.bumptech.glide.load.model.ModelLoader;
    import com.bumptech.glide.load.model.ModelLoaderFactory;

    import java.io.InputStream;

    import okhttp3.OkHttpClient;

    public class OkHttpUrlLoader implements ModelLoader<GlideUrl, InputStream> {

    public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> {
    private static volatile OkHttpClient internalClient;
    private OkHttpClient client;

    private static OkHttpClient getInternalClient() {
    if (internalClient == null) {
    synchronized (Factory.class) {
    if (internalClient == null) {
    internalClient = new OkHttpClient();
    }
    }
    }
    return internalClient;
    }

    public Factory() {
    this(getInternalClient());
    }

    public Factory(OkHttpClient client) {
    this.client = client;
    }

    @Override
    public ModelLoader<GlideUrl, InputStream> build(Context context, GenericLoaderFactory factories) {
    return new OkHttpUrlLoader(client);
    }

    @Override
    public void teardown() {
    }
    }

    private final OkHttpClient client;

    public OkHttpUrlLoader(OkHttpClient client) {
    this.client = client;
    }

    @Override
    public DataFetcher<InputStream> getResourceFetcher(GlideUrl model, int width, int height) {
    return new OkHttpStreamFetcher(client, model);
    }
    }

     还有一个是okhttp信任证书。

    SSLSocketClient.java

    /**
    * <p>Title: SSLSocketClient.java</p>
    * <p>Description: </p>
    * <p>Copyright: Copyright (c) 2017</p>
    * <p>Company: www.baidudu.com</p>
    * @author tsj
    * @date 2018 10 18
    * @version 1.0
    */
    package com.example.androidtest;

    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;

    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.X509TrustManager;

    import android.util.Log;

    /**
    * <p>Title: SSLSocketClient</p>
    * <p>Description: </p>
    * @author tsj
    * @date 2018 10 18
    */

    public class SSLSocketClient {

    //获取这个SSLSocketFactory
    public 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);
    }
    }

    //获取TrustManager
    private static TrustManager[] getTrustManager() {
    TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager() {

    @Override
    public X509Certificate[] getAcceptedIssuers() {
    return new X509Certificate[]{};
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain,
    String authType) throws CertificateException {
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain,
    String authType) throws CertificateException {
    }
    }
    };
    return trustAllCerts;
    }

    //获取HostnameVerifier
    public static HostnameVerifier getHostnameVerifier() {
    HostnameVerifier hostnameVerifier = new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
    // TODO Auto-generated method stub
    return true;
    }
    };
    return hostnameVerifier;
    }
    }

    在AndroidManifest.xml里面配置

    <meta-data
    android:name="com.example.androidtest.https.OkHttpGlideModule"
    android:value="GlideModule" />

    然后Activity是这样调用的

    package com.example.androidtest;


    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ImageView;

    import com.bumptech.glide.Glide;

    public class MainActivity extends Activity {

    private ImageView imageView;
    private Button mButton;
    private String url="https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E7%99%BE%E5%BA%A6%E5%9B%BE%E7%89%87&step_word=&hs=0&pn=5&spn=0&di=94952282390&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=99355280%2C609648180&os=1002106675%2C4110592367&simid=2009090768%2C841445828&adpicid=0&lpn=0&ln=1902&fr=&fmq=1539876892817_R&fm=&ic=undefined&s=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=&bdtype=13&oriquery=&objurl=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2Fd01373f082025aaf5d53a7e3f0edab64034f1ab1.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Frwtxtg_z%26e3Bv54AzdH3Fri5p5v5ry6t2ipAzdH3F8nl9cmma9&gsm=0&rpstart=0&rpnum=0&islist=&querylist=";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    imageView = (ImageView) findViewById(R.id.image);
    mButton = (Button) findViewById(R.id.button);
    mButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
    Glide.with(getApplicationContext()).load(url)
    .placeholder(R.drawable.ic_launcher)
    .error(R.drawable.ic_launcher)
    .into(imageView);
    }
    });

    }

    }

    这里的url是测试用的,建议将url换成你们自己的。

    最后附上一张图片

     

    参考文章:https://blog.csdn.net/u014752325/article/details/73217577

         https://blog.csdn.net/u014752325/article/details/73185351

  • 相关阅读:
    mac c++编译出现segmentation fault :11错误
    ssh 连接缓慢解决方法
    237. Delete Node in a Linked List
    203. Remove Linked List Elements
    Inversion of Control Containers and the Dependency Injection pattern
    82. Remove Duplicates from Sorted List II
    83. Remove Duplicates from Sorted List
    SxsTrace
    使用CCleaner卸载chrome
    decimal and double ToString problem
  • 原文地址:https://www.cnblogs.com/suicode/p/9814002.html
Copyright © 2011-2022 走看看