让okhttp使用更简单

        之前一直是用volley库的,所涉及的项目通信数据量不大,但是通信频繁,volley短小精悍,哈哈,自己扩展起来也方便,但是volley也不并不是完美到任何项目都完美覆盖,对于一些通信数据量大,需要大文件下载,图片下载涉及场景较多的还是建议考虑下okHttp咯。 以下,根据自己项目的要求,封装了okhttp网络基础通信模块,严格的说是整理了一下网上各路大神的套路,让自己用起来更加方便快捷,主要封装的功能包括支持https通信,get请求,post请求,文件上传,网络日志打印。基本项目中需要用到的网络通信功能都在里面了。

	allprojects {
		repositories {
			...
			maven { url 'https://www.jitpack.io' }
		}
	}

	dependencies {
	        compile 'com.github.gugu0087:GuOkhttps:1.1.0'
	}

1.https的封装

将你生成的证书文件(xx.cer)cop到assets目录,没有就新建。下面是封装的支持htpps的类。

public class HttpsUtils
{
    public static class SSLParams
    {
        public SSLSocketFactory sSLSocketFactory;
        public X509TrustManager trustManager;
    }

    public static SSLParams getSslSocketFactory(InputStream[] certificates, InputStream bksFile, String password)
    {
        SSLParams sslParams = new SSLParams();
        try
        {
            TrustManager[] trustManagers = prepareTrustManager(certificates);
            KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            X509TrustManager trustManager = null;
            if (trustManagers != null)
            {
                trustManager = new MyTrustManager(chooseTrustManager(trustManagers));
            } else
            {
                trustManager = new UnSafeTrustManager();
            }
            sslContext.init(keyManagers, new TrustManager[]{trustManager},null);
            sslParams.sSLSocketFactory = sslContext.getSocketFactory();
            sslParams.trustManager = trustManager;
            return sslParams;
        } catch (NoSuchAlgorithmException e)
        {
            throw new AssertionError(e);
        } catch (KeyManagementException e)
        {
            throw new AssertionError(e);
        } catch (KeyStoreException e)
        {
            throw new AssertionError(e);
        }
    }

    private class UnSafeHostnameVerifier implements HostnameVerifier
    {
        @Override
        public boolean verify(String hostname, SSLSession session)
        {
            return true;
        }
    }

    private static class UnSafeTrustManager implements X509TrustManager
    {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException
        {
        }

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

        @Override
        public X509Certificate[] getAcceptedIssuers()
        {
            return new java.security.cert.X509Certificate[]{};
        }
    }

    private static TrustManager[] prepareTrustManager(InputStream... certificates)
    {
        if (certificates == null || certificates.length <= 0) return null;
        try
        {

            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates)
            {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
                try
                {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e)

                {
                }
            }
            TrustManagerFactory trustManagerFactory = null;

            trustManagerFactory = TrustManagerFactory.
                    getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);

            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

            return trustManagers;
        } catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        } catch (CertificateException e)
        {
            e.printStackTrace();
        } catch (KeyStoreException e)
        {
            e.printStackTrace();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;

    }

    private static KeyManager[] prepareKeyManager(InputStream bksFile, String password)
    {
        try
        {
            if (bksFile == null || password == null) return null;

            KeyStore clientKeyStore = KeyStore.getInstance("BKS");
            clientKeyStore.load(bksFile, password.toCharArray());
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(clientKeyStore, password.toCharArray());
            return keyManagerFactory.getKeyManagers();

        } catch (KeyStoreException e)
        {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e)
        {
            e.printStackTrace();
        } catch (CertificateException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers)
    {
        for (TrustManager trustManager : trustManagers)
        {
            if (trustManager instanceof X509TrustManager)
            {
                return (X509TrustManager) trustManager;
            }
        }
        return null;
    }


    private static class MyTrustManager implements X509TrustManager
    {
        private X509TrustManager defaultTrustManager;
        private X509TrustManager localTrustManager;

        public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException
        {
            TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            var4.init((KeyStore) null);
            defaultTrustManager = chooseTrustManager(var4.getTrustManagers());
            this.localTrustManager = localTrustManager;
        }


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

        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
        {
            try
            {
                defaultTrustManager.checkServerTrusted(chain, authType);
            } catch (CertificateException ce)
            {
                localTrustManager.checkServerTrusted(chain, authType);
            }
        }


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

使用方法很简单。在初始化的时候的调用(初始化的位置看你需要网络的时机咯,application初始化的时候也可以)。这个初始化方法要自己写,我自己写了三个(其实最后一个就可以了,其他2个有人喜欢就用)

public static void initOkhttp(Context context) {
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(new LoggerInterceptor(TAG, true, context))
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
            //其他配置
            .build();
    OkHttpUtils.initClient(okHttpClient);
}

public static void initHttpsOkHttp(Context context) {
    HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
            //其他配置
            .addInterceptor(new LoggerInterceptor(TAG, true, context))
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
            .build();
    OkHttpUtils.initClient(okHttpClient);
}

public static void initHttpOkhttp(Context context, boolean isSupportHttps) {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    if (isSupportHttps) {
        HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);
        builder.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager);
    }
    //其他配置
    builder.addInterceptor(new LoggerInterceptor(TAG, true, context));
    builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS);
    builder.readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS);
    OkHttpUtils.initClient(builder.build());
}

2.get,post,请求实例,通过一个DataManager 来管理,避免很多重复代码,不喜欢写多余代码。

 
  
public class DataManager {

    public static DataManager instance = null;
    public final String MULTIPART_FORM_DATA = "image/*";       // 指明要上传的文件格式

    DataManager() {

    }

    public static DataManager getInstance() {
        if (instance == null) {
            instance = new DataManager();
        }
        return instance;
    }

    private String getToken() {
        return PreferencesUtils.getString("token");

    }

    public RequestCall sendGetRequestData(String url, Map, String> params) {
        String token = getToken();
        GetBuilder getBuilder = OkHttpUtils.get().url(url);
        if (params != null) {
            getBuilder.params(params);
        }
        if (token != null) {
            getBuilder.addHeader("X-Authorization", "bearer " + token);
        }
        return getBuilder.build();
    }

    public RequestCall sendPostRequestData(String url, JSONObject params, MediaType mediaType) {
        String token = getToken();
        PostStringBuilder postStringBuilder = OkHttpUtils.postString().url(url);
        postStringBuilder.addHeader("X-Authorization", "bearer " + token);
        postStringBuilder.mediaType(mediaType);
        postStringBuilder.content(params.toString());
        return postStringBuilder.build();
    }

    public RequestCall sendPostRequestData(String url, JSONObject params) {
        String token = getToken();
        PostStringBuilder postStringBuilder = OkHttpUtils.postString().url(url);
        postStringBuilder.mediaType(MediaType.parse("application/json; charset=utf-8"));
        postStringBuilder.addHeader("X-Authorization", "bearer " + token);
        postStringBuilder.content(params.toString());

        return postStringBuilder.build();
    }

    public void sendPostRequestData(String url, JSONObject params, final IGetResponseCodeListener listener) {
        String token = getToken();
        PostStringBuilder postStringBuilder = OkHttpUtils.postString().url(url);
        postStringBuilder.mediaType(MediaType.parse("application/json; charset=utf-8"));
        postStringBuilder.addHeader("X-Authorization", "bearer " + token);
        postStringBuilder.content(params.toString());
        postStringBuilder.build().execute(new Callback() {
            @Override
            public Object parseNetworkResponse(final Response response, final int i) throws Exception {
                final int code = response.code();
                final String string = response.body().string();
                ApplicationHolder.getInstance().postMainRunnable(new Runnable() {
                    @Override
                    public void run() {
                        if(listener!=null){
                            listener.onSuccessResponse(code,string);
                        }
                    }
                });
                return null;
            }

            @Override
            public void onError(Call call, Exception e, int i) {
                if(listener!=null){
                    listener.onFailedResponse(e.getMessage());
                }
            }

            @Override
            public void onResponse(Object o, int i) {
                
            }
        });
    }

    public void sendPostFileData(String url,File file, final IGetResponseCodeListener listener) {
        String token = getToken();
        PostFileBuilder postFileBuilder = OkHttpUtils.postFile();
        postFileBuilder.isFormSubmitFile = true;
        postFileBuilder.mediaType(MediaType.parse(MULTIPART_FORM_DATA));
        postFileBuilder.addHeader("X-Authorization", "bearer " + token);
        postFileBuilder.file(file);
        postFileBuilder.url(url);
        postFileBuilder.build().execute(new Callback() {
            @Override
            public Object parseNetworkResponse(final Response response, final int i) throws Exception {
                final int code = response.code();
                final String string = response.body().string();
                ApplicationHolder.getInstance().postMainRunnable(new Runnable() {
                    @Override
                    public void run() {
                        if(listener!=null){
                            listener.onSuccessResponse(code,string);
                        }
                    }
                });

                return null;
            }

            @Override
            public void onError(Call call, Exception e, int i) {
               if(listener!=null){
                   listener.onFailedResponse(e.getMessage());
               }
            }

            @Override
            public void onResponse(Object o, int i) {

            }
        });

    }
}

PS:(1)这个是token设置,读取token,很多项目会要求token过期校验,token存在了prefence里,各位大神自行存,登录的时候记得先保存,要不然拿到的是空,这个DataManager各自根据自己的逻辑来写就可以了,这是我图省事写的。

让okhttp使用更简单_第1张图片

3.使用起来就很方便了,

//登录 post

private void login() {
    JSONObject params = new JSONObject();
    try {
        params.put("loginName", "test");
        params.put("password", "123456");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    DataManager.getInstance().sendPostRequestData(url_login, params)
            .execute(new GenericsCallback(new JsonGenericsSerializator()) {
                @Override
                public void onError(Call call, Exception e, int id) {
                    Log.d("xyc", "onError: e=" + e.getMessage());
                }

                @Override
                public void onResponse(User response, int id) {
                    Log.d("xyc", "onResponse: response=" + response);
                }

            });
}

get请求数据

让okhttp使用更简单_第2张图片

上传文件,这里是图片

public void okHttpUpload() {

    String path = "/storage/emulated/0/DCIM/camera/IMG_20180301_141314.jpg";
    File file = new File(path);
    String url = url_upload;
    DataManager.getInstance().sendPostFileData(url, file, new IGetResponseCodeListener() {
        @Override
        public void onSuccessResponse(int code, String response) {

        }

        @Override
        public void onFailedResponse(String msg) {

        }
    });
}

4.网络 日志打印,保存在包的files文件夹。

让okhttp使用更简单_第3张图片

让okhttp使用更简单_第4张图片

    ps:tag as上打印的日志的tag,自己定义,showResponse true as上打印日志,并且写日志保存到本地;

5.token失效,通知其他页面 退出登录,这里用了eventBus,很明显强制实现,感觉有坑,但自己测试没有发现问题,在baseactivity里订阅这个事件,是可以正常接收,并做 出相关的处理的。。实在没有想好怎么处理这个回调,各位视而不见吧,也欢迎各位提个意见。

让okhttp使用更简单_第5张图片

     以上这些更多的是整理,仅仅是记录下年轻时候挖的坑,更适合我自己的项目,发现问题,我会在自己项目及时调整处理,各位用的时候慎重考虑!

github地址:点击打开链接

你可能感兴趣的:(Android进阶知识)