版权声明:本文为延成原创文章,转载请标明出处
Retrofit网络请求工具的封装
首先导包
复制代码
1
2
3
4
5
6
7
8
9implementation 'com.squareup.okhttp3:okhttp:3.12.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0' implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:converter-gson:2.5.0' implementation 'com.squareup.retrofit2:converter-scalars:2.5.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
Retrofit工具类的封装RetrofitHelper.calss
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150/** * @author Mr.release * @create 2019/3/29 * @Describe */ public class RetrofitHelper { private static final String HEAD_LINE_NEWS = "T1348647909107"; private static OkHttpClient.Builder builder; static { initOkHttpClient(); } private static void initOkHttpClient() { if (builder == null) { synchronized (RetrofitHelper.class) { if (builder == null) { HttpsSSLUtils.SSLParams sslParams = HttpsSSLUtils.getSslSocketFactory(); HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); if (BuildConfig.DEBUG) { interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); } else { interceptor.setLevel(HttpLoggingInterceptor.Level.NONE); } Cache cache = new Cache(new File(App.getInstance().getCacheDir(), "HttpCache"), 1024 * 1024 * 10); builder = new OkHttpClient.Builder() .cache(cache) .addInterceptor(interceptor) .addInterceptor(new headerIntercepteor()) .addNetworkInterceptor(new CacheInterceptor()) .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager) .retryOnConnectionFailure(true) .connectTimeout(30, TimeUnit.SECONDS) .writeTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS); } } } } private static <T> T createApi(String baseUrl, Class<T> cls) { Retrofit retrofit = new Retrofit.Builder() .client(builder.build()) .baseUrl(baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) // .addConverterFactory(StringConverterFactory.create()) .build(); return retrofit.create(cls); } private static NewsServiceApi createNewsServiceApi() { return createApi(BaseURL.NEWS_HOST, NewsServiceApi.class); } private static RecommendServiceApi createRecommendServiceApi() { return createApi(BaseURL.RECOMMEND_HOST, RecommendServiceApi.class); } /** * 打印返回的json数据拦截器 */ private static class headerIntercepteor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { final Request request = chain.request(); Buffer requestBuffer = new Buffer(); if (request == null) throw new RuntimeException("Request返回值不能为空"); RequestBody requestBody = request.body(); if (requestBody != null) requestBody.writeTo(requestBuffer); else Logger.d("request.body() == null"); //打印url信息 Logger.w(request.url() + (requestBody != null ? "?" + _parseParams(requestBody, requestBuffer) : "")); final Response response = chain.proceed(request); if (response == null) { throw new RuntimeException("Response返回值不能为空"); } return response; } } @NonNull private static String _parseParams(RequestBody body, Buffer requestBuffer) throws UnsupportedEncodingException { if (body.contentType() != null && !body.contentType().toString().contains("multipart")) { return URLDecoder.decode(requestBuffer.readUtf8(), "UTF-8"); } return "null"; } private static class UserAgentInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Request requestWithUserAgent = originalRequest.newBuilder() .removeHeader("User-Agent") .addHeader("User-Agent", BaseURL.COMMON_UA_STR) .build(); return chain.proceed(requestWithUserAgent); } } private static class CacheInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { // 有网络时 设置缓存超时时间1个小时 int maxAge = 60 * 60; // 无网络时,设置超时为1周 int maxStale = 60 * 60 * 24 * 7; Request request = chain.request(); if (CommonUtil.isNetworkAvailable(App.getInstance())) { //有网络时只从网络获取 request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build(); } else { //无网络时只从缓存中读取 request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build(); } Response response = chain.proceed(request); if (CommonUtil.isNetworkAvailable(App.getInstance())) { response = response.newBuilder() .removeHeader("Pragma") .header("Cache-Control", "public, max-age=" + maxAge) .build(); } else { response = response.newBuilder() .removeHeader("Pragma") .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale) .build(); } return response; } }
HttpsSSLUtils.calss
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169/** * @author Mr.release * @create 2019/3/29 * @Describe */ public class HttpsSSLUtils { public static class SSLParams { public SSLSocketFactory sSLSocketFactory; public X509TrustManager trustManager; } public static SSLParams getSslSocketFactory() { return getSslSocketFactoryBase(null, null, null); } /** * https单向认证 * 可以额外配置信任服务端的证书策略,否则默认是按CA证书去验证的,若不是CA可信任的证书,则无法通过验证 */ public static SSLParams getSslSocketFactory(X509TrustManager trustManager) { return getSslSocketFactoryBase(trustManager, null, null); } /** * https单向认证 * 用含有服务端公钥的证书校验服务端证书 */ public static SSLParams getSslSocketFactory(InputStream... certificates) { return getSslSocketFactoryBase(null, null, null, certificates); } /** * https双向认证 * bksFile 和 password -> 客户端使用bks证书校验服务端证书 * certificates -> 用含有服务端公钥的证书校验服务端证书 */ public static SSLParams getSslSocketFactory(InputStream bksFile, String password, InputStream... certificates) { return getSslSocketFactoryBase(null, bksFile, password, certificates); } /** * https双向认证 * bksFile 和 password -> 客户端使用bks证书校验服务端证书 * X509TrustManager -> 如果需要自己校验,那么可以自己实现相关校验,如果不需要自己校验,那么传null即可 */ public static SSLParams getSslSocketFactory(InputStream bksFile, String password, X509TrustManager trustManager) { return getSslSocketFactoryBase(trustManager, bksFile, password); } private static SSLParams getSslSocketFactoryBase(X509TrustManager trustManager, InputStream bksFile, String password, InputStream... certificates) { SSLParams sslParams = new SSLParams(); try { KeyManager[] keyManagers = prepareKeyManager(bksFile, password); TrustManager[] trustManagers = prepareTrustManager(certificates); X509TrustManager manager; if (trustManager != null) { //优先使用用户自定义的TrustManager manager = trustManager; } else if (trustManagers != null) { //然后使用默认的TrustManager manager = chooseTrustManager(trustManagers); } else { //否则使用不安全的TrustManager manager = UnSafeTrustManager; } // 创建TLS类型的SSLContext对象, that uses our TrustManager SSLContext sslContext = SSLContext.getInstance("TLS"); // 用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书 // 第一个参数是授权的密钥管理器,用来授权验证,比如授权自签名的证书验证。第二个是被授权的证书管理器,用来验证服务器端的证书 sslContext.init(keyManagers, new TrustManager[]{manager}, null); // 通过sslContext获取SSLSocketFactory对象 sslParams.sSLSocketFactory = sslContext.getSocketFactory(); sslParams.trustManager = manager; return sslParams; } catch (NoSuchAlgorithmException e) { throw new AssertionError(e); } catch (KeyManagementException e) { throw new AssertionError(e); } } 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 kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(clientKeyStore, password.toCharArray()); return kmf.getKeyManagers(); } catch (Exception e) { e.printStackTrace(); } return null; } private static TrustManager[] prepareTrustManager(InputStream... certificates) { if (certificates == null || certificates.length <= 0) return null; try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); // 创建一个默认类型的KeyStore,存储我们信任的证书 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); int index = 0; for (InputStream certStream : certificates) { String certificateAlias = Integer.toString(index++); // 证书工厂根据证书文件的流生成证书 cert Certificate cert = certificateFactory.generateCertificate(certStream); // 将 cert 作为可信证书放入到keyStore中 keyStore.setCertificateEntry(certificateAlias, cert); try { if (certStream != null) certStream.close(); } catch (IOException e) { e.printStackTrace(); } } //我们创建一个默认类型的TrustManagerFactory TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); //用我们之前的keyStore实例初始化TrustManagerFactory,这样tmf就会信任keyStore中的证书 tmf.init(keyStore); //通过tmf获取TrustManager数组,TrustManager也会信任keyStore中的证书 return tmf.getTrustManagers(); } 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; } /** * 为了解决客户端不信任服务器数字证书的问题,网络上大部分的解决方案都是让客户端不对证书做任何检查, * 这是一种有很大安全漏洞的办法 */ public static X509TrustManager UnSafeTrustManager = new 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 X509Certificate[]{}; } }; /** * 此类是用于主机名验证的基接口。 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配, * 则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。策略可以是基于证书的或依赖于其他验证方案。 * 当验证 URL 主机名使用的默认规则失败时使用这些回调。如果主机名是可接受的,则返回 true */ public static HostnameVerifier UnSafeHostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; }
HttpUtils.calss
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42/** * @author Mr.release * @create 2019/8/2 * @Describe */ public class HttpUtils { @SuppressLint("CheckResult") public static <T> void ext(Flowable<T> flowable, IView view, boolean isShowLoading) { flowable.compose(RxUtil.rxSchedulerHelper()) .doOnSubscribe(new Consumer<Subscription>() { @Override public void accept(Subscription subscription) throws Exception { if (isShowLoading) view.showLoading(); } }) .as(RxUtil.bindLifecycle((LifecycleOwner) view)) .subscribeWith(new CommonSubscriber<T>() { @Override protected void _onNext(T bean) { Logger.d("_onNext: " + bean); view.loadData(bean); } @Override protected void _onError(String message) { Logger.d("_onError: " + message); if (isShowLoading) view.showError(); else view.showError(App.getInstance().getString(R.string.data_error)); } @Override protected void _onComplete() { view.hideLoading(); } }); } }
最后
以上就是兴奋小天鹅最近收集整理的关于Retrofit网络请求工具的封装的全部内容,更多相关Retrofit网络请求工具内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复