使用Volley时SSL异常 [英] SSL Exception when using Volley

查看:118
本文介绍了使用Volley时SSL异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Android中使用Volley来执行我的应用程序请求.不幸的是,我收到以下错误:

I'm using Volley in Android to perform my app requests. Unfortunately, I'm getting the following error:

com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x61e15f78: Failure in SSL library, usually a protocol error
    error:1407743E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert inappropriate fallback (external/openssl/ssl/s23_clnt.c:744 0x5b647c58:0x00000000)

我正在ViewPager中使用两个Fragments,它们在onResume期间请求其内容.请求网址基本上是相同的,只是用于查询参数(用于设置内容的类型,例如趋势与热门).

I'm using two Fragments, inside a ViewPager, which request their content during onResume. The requests url is basically the same but for a query parameter (which set the type of content, e.g. trending vs hot).

URL的格式为https://host/api/content?type={hot/trending}.授权是通过请求标头完成的.

The url is in the form https://host/api/content?type={hot/trending}. Authorization is done through the request header.

关于此异常的怪异部分是,两个请求中只有一个失败,并且该请求会不时变化.在它们之间添加了延迟之后,异常停止发生了(奇怪地指向某些竞争条件?).但这似乎是一个不好的解决方法,我想以正确的方式解决此问题.

The weird part about this exception is that only one of the two requests fail and it varies which one from time to time. After I added a delay between them, the exception stopped occurring (oddly pointing to some race condition?). But this seems a bad workaround and I'd like to solve this the right way.

是否有任何可能的原因的想法?

Any thoughts on what could be the cause of it?

使用提供队列的单例,以标准方式创建请求,如下所示:

The request is created the standard way, using a singleton providing the queue, as follows:

final RequestQueue requestQueue = RequestQueueSingleton.getInstance(getActivity()).getRequestQueue();
final GsonRequestGet<SearchApiWrapper> gsonRequest = new GsonRequestGet<>(clazz, url,successListener, errorListener);
gsonRequest.setRetryPolicy(new DefaultRetryPolicy(3000, 3, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
gsonRequest.setTag(mTag);
requestQueue.add(gsonRequest);

这是单例课程:

public class RequestQueueSingleton {

    private static RequestQueueSingleton mInstance;
    private RequestQueue mRequestQueue;
    private Context mContext;

    public RequestQueueSingleton(Context context) {
        mContext = context;
        mRequestQueue = getRequestQueue();
    }

    /**
     * Returns a instance of this singleton
     */
    public static synchronized RequestQueueSingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new RequestQueueSingleton(context);
        }
        return mInstance;
    }

    /**
     * Returns instance of the request queue
     */
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
        }
        return mRequestQueue;
    }
}

推荐答案

在我们发表评论之后,这可能可以为您提供帮助:

After our comments maybe this can help you:

您的requestQueue:

static {
    requestQueue = Volley.newRequestQueue(Application.getContext(), new HurlStack(null, ClientSSLSocketFactory.getSocketFactory()));
}

ClientSSLSocketFactory:

public class ClientSSLSocketFactory extends SSLCertificateSocketFactory {
    private SSLContext sslContext;

    public static SSLSocketFactory getSocketFactory(){
        try
        {
            X509TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {}

                public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {}

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[] { tm }, null);

            SSLSocketFactory ssf = ClientSSLSocketFactory.getDefault(10000, new SSLSessionCache(Application.getInstance()));

            return ssf;
        } catch (Exception ex) {
            return null;
        }
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }
}

这篇关于使用Volley时SSL异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆