retrofit2设置超时_Retrofit2 + OkHttp3 配置及Interceptor原理

前段时间在给公司的新app做一些基础模块的封装,把Http模块中的一些基础配置,比如设置链接超时、Http Log Interceptor、Access Token Interceptor、Status Code Interceptor,以及Json转换、RxJava适配等设置做一下分享,再简单说说OkHttp Interceptor原理。

基本配置

OkHttp配置

OkHttp主要采用Builder模式进行配置

1234567891011121314151617HttpLoggingInterceptor.Logger CUSTOM = new HttpLoggingInterceptor.Logger() {@Overridepublic void log(String message) {Platform.get().log(INFO, "OkHttp-idtk: " + message, null);}};HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(CUSTOM);loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).writeTimeout(5, TimeUnit.SECONDS).connectTimeout(15, TimeUnit.SECONDS).retryOnConnectionFailure(true).addInterceptor(statusInterceptor).addInterceptor(loggingInterceptor).addNetworkInterceptor(tokenInterceptor).build();

o    retryOnConnectionFailure设置为true,表示请求失败后将会重连。

o    HttpLoggingInterceptor用于拦截网络请求和响应,并输出Log,我在输出log的标识方面稍微修改了一下,便于使用时的区别。等级分为NONE/BASIC/HEADERS/BODY,其中BODY打印出的最为详细。

o    addInterceptor与addNetworkInterceptor都是增加OkHttp的网络请求拦截器,但是其中是有一定区别的,前者是添加在与服务器连接之前和之后,后者是添加在与服务器建立连接和发起请求的之间。

o    tokenInterceptor 是用来设置的token的拦截器,用于网络请求token的统一添加,具体内容会在接下来说明。

o    statusInterceptor 用于响应返回状态码的处理,比如token过期、注册码无效等状态的处理。

token拦截器

让所有网络请求都添加上token12345678910111213141516171819@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();String url = request.url().toString();if (NetConfig.needAddToken(request)) {Uri uri = Uri.parse(url);Set oldParam = uri.getQueryParameterNames();if (!oldParam.contains("token")){String token = getToken();if (oldParam.size() >0){url += "&token=" + token;}else {url += "?token=" +token;}}request = request.newBuilder().url(url).build();}return chain.proceed(request);}

o    对于登录请求等情况,是不需要添加token的,所以在needAddToken方法中进行了判断。

o    我这里后台的要求是把token放在url中,所以我进行了如上的写法,你也可以根据自己的需求进行修改。

状态码拦截

对于后台定义的各种状态码进行处理1234567891011121314151617181920212223@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();Response response = chain.proceed(request);BaseResult data = new Gson().fromJson(response.body().string(), BaseResult.class);if (data == null) {throw new RuntimeException("返回数据结构不合法: " + response.body().string());}int status = data.status;switch (status){case NetConfig.TOKEN:throw new TokenException(data.msg);case NetConfig.REGISTER_CODE:throw new RegisterException(data.msg);}return response;}public class BaseResult {public int status;public String msg;public JsonElement data;}

o    BaseResult是根据与后台的协定设置的,这里首先对data是否为null进行了检测。

o    在获取状态码之后,对其进行token失效和注册码失效的检测,这里处理抛出异常,之后可以在使用时的基类进行统一处理。当然你也可以使用接口等别的方式进行处理。

Retrofit配置123456retrofit = new Retrofit.Builder().client(buildClient()).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).baseUrl(baseUrl).build();

o    addConverterFactory 添加Gson转换器

o    addCallAdapterFactory 添加Rxjava2适配器

拦截器原理

因为之前写过文章分析,所以这里便不再赘述,而对于OkHttp,现在来简单说说其拦截器原理。

OkHttp的使用我想大家都知道,在调用client.newCall(request)将会调用到RealCall.newRealCall(this, request, false);方法,之后将会调用到RealCall.getResponseWithInterceptorChain()函数,而在其中将进行拦截器链的构建。1234567891011121314151617181920212223242526Response getResponseWithInterceptorChain() throws IOException {// Build a full stack of interceptors.List interceptors = new ArrayList<>();// client中配置的interceptorsinterceptors.addAll(client.interceptors());// 重定向与失败重试interceptors.add(retryAndFollowUpInterceptor);// 用户的请求头处理,响应处理// (Cookie持久性策略)interceptors.add(new BridgeInterceptor(client.cookieJar()));// 缓存请求、响应缓存的写入 (客户端设置的缓存策略)interceptors.add(new CacheInterceptor(client.internalCache()));// 与服务器建立连接interceptors.add(new ConnectInterceptor(client));if (!forWebSocket) {// client配置的networkInterceptors,用于观察请求和响应interceptors.addAll(client.networkInterceptors());}// 发送请求,读取服务器的响应interceptors.add(new CallServerInterceptor(forWebSocket));// 设置完整的OkHttp拦截链Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest);// 调用链中的下一个拦截器,在这里是开始调用第一个拦截器return chain.proceed(originalRequest);}

可以看出拦截器列表是从interceptors开始添加的,也就是之前说的HttpLoggingInterceptor、StatusInterceptor,之后添加重定向、cookie、缓存、连接建立的拦截器,然后添加上networkInterceptors,也就是我们之前说的TokenInterceptor,最后通过RealInterceptorChain调用proceed接口启动拦截器。

如果你查看上面各个拦截器的源码,包括我上面自定义的三个拦截器,你会发现其中几乎都使用了chain.proceed方法来生成response,当然CallServerInterceptor其中并没有这个方法,因为它是真正使用去进行请求的拦截器。根据这些我们就可以绘制出一个事件流在拦截其中的过程:

我们可以在CallServerInterceptor之前对request的header、url等参数进行检测和配置,比如我们自定义的TokenInterceptor,在CallServerInterceptor之后我们可以对response的code、body等进行检测和配置,比如我们之前定义的StatusInterceptor,而HttpLoggingInterceptor则是对request和response都进行检测和配置。

小结

当然Retrofit+OkHttp还有更多的属性配置,比如证书、Cookie等,但这些属性在网络请求中的实现都是在OkHttp Interceptor中进行的,感兴趣的同学建议阅读下源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值