关于Retrofit2+Okhttp3实现统一添加请求参数和重定向
Posted LeBron_Six
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Retrofit2+Okhttp3实现统一添加请求参数和重定向相关的知识,希望对你有一定的参考价值。
android开发中难免会遇到一些比较“不友好”的服务端接口。比如以前遇到的json数据中,某个字段偶尔为Object,偶尔为List…
最近遇到的一个问题就是:所有请求接口都要增加一个token参数… 并且token参数有可能过期,比如请求某一条接口,如果token失效则在该请求的响应中把新的token带回来,客户端就得用新的token再次发送该请求,类似重定向。
token失效的stateCode为3,新的token在data字段中返回。如下:
"stateCode":3,
"data":"E78kH6",
"errorMsg":null
庆幸的是,Okhttp提供了强大的拦截器功能,是一种能够监控,重写,重试调用的强大机制。
public class TokenInterceptord implements Interceptor
private final String TAG = "respond";
@Override
public Response intercept(Chain chain) throws IOException
Request oldRequest = chain.request();
String url = oldRequest.url().toString();
Response response = null;
// 新的请求,添加参数
Request newRequest = addParam(oldRequest);
response = chain.proceed(newRequest);
ResponseBody value = response.body();
byte[] resp = value.bytes();
String json = new String(resp, "UTF-8");
// 判断stateCode值
try
JSONObject jsonObject = new JSONObject(json);
int stateCode = jsonObject.optInt("stateCode");
if (stateCode == 3)
String data = jsonObject.optString("data");
Log.d(TAG, "token失效,新的token:" + data);
DataStorageUtils.saveToken(data);
// token失效,重新执行请求
Request newTokenRequest = addParam(oldRequest);
response = chain.proceed(newTokenRequest);
else
// 这里值得注意。由于前面value.bytes()把响应流读完并关闭了,所以这里需要重新生成一个response,否则数据就无法正常解析了
response = response.newBuilder()
.body(ResponseBody.create(null, resp))
.build();
catch (Exception e)
return response;
/**
* 添加公共参数
*
* @param oldRequest
* @return
*/
private Request addParam(Request oldRequest)
HttpUrl.Builder builder = oldRequest.url()
.newBuilder()
.setEncodedQueryParameter("lversion", PackagesUtils.getAppVersionName())
.setEncodedQueryParameter("token", DataStorageUtils.getToken());
Request newRequest = oldRequest.newBuilder()
.method(oldRequest.method(), oldRequest.body())
.url(builder.build())
.build();
return newRequest;
当然,也可以为请求或响应添加Header。
Request request = oldRequest.newBuilder()
.header("Content-Encoding", "gzip")
.build();
Response response = response.newBuilder()
.header("Content-Encoding", "gzip")
.build();
然后为OkHttp配置一个拦截器。
public static OkHttpClient getOkHttpClient()
Interceptor interceptor = new TokenInterceptor();
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(30 * 1000, TimeUnit.MILLISECONDS)
.readTimeout(30 * 1000, TimeUnit.MILLISECONDS)
.addInterceptor(interceptor)
.addInterceptor(new HttpLoggingInterceptor(new MyLog()).setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
return client;
Retrofit 使用 Okhttp作为client
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(getOkHttpClient())
.build();
Api api = retrofit.create(Api.class);
以上是关于关于Retrofit2+Okhttp3实现统一添加请求参数和重定向的主要内容,如果未能解决你的问题,请参考以下文章
Android网络实战篇——OkHttp3(Retrofit2)五种缓存模式的实现
Retrofit2.0 ,OkHttp3完美同步持久Cookie实现免登录
Android Okhttp3+Retrofit2网络加载效率优化