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各自根据自己的逻辑来写就可以了,这是我图省事写的。
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请求数据
上传文件,这里是图片
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文件夹。
ps:tag as上打印的日志的tag,自己定义,showResponse true as上打印日志,并且写日志保存到本地;
5.token失效,通知其他页面 退出登录,这里用了eventBus,很明显强制实现,感觉有坑,但自己测试没有发现问题,在baseactivity里订阅这个事件,是可以正常接收,并做 出相关的处理的。。实在没有想好怎么处理这个回调,各位视而不见吧,也欢迎各位提个意见。
以上这些更多的是整理,仅仅是记录下年轻时候挖的坑,更适合我自己的项目,发现问题,我会在自己项目及时调整处理,各位用的时候慎重考虑!
github地址:点击打开链接