原因为OkHttp请求回调中response.body().string()只能有效调用一次,而我使用了两次:
String result = response.body().string();
Log.e(TAG, "onResponse - " + response.body().string() );//打印时又使用了一次
如果添加拦截时,必须取response 中的值,那么在取出来知乎应该要重新创建
//response.body().string() 只能调用一次 就会close 所以要重建response
response = response.newBuilder()
.body(ResponseBody.create(mediaType, responseBody))
.build();
自定义 Intecepter
public class AuthenticatorInterceptor implements Interceptor {
private String baseUrl;
String url;
public AuthenticatorInterceptor(String baseurl) {
this.baseUrl = baseurl;
url = baseUrl + Constants.AccountUrl.PREFIX + Constants.AccountUrl.PATH_USER_REFRESH;
FLog.i("HttpLog", "AuthenticatorInterceptor url=" + url);
}
@Override
public Response intercept(Chain chain) throws IOException {
FLog.i("HttpLog", "AuthenticatorInterceptor");
// 获取请求
Request request = chain.request();
// 获取响应
Response response = chain.proceed(request);
// 在这里判断是不是是token失效
// 当然,判断条件不会这么简单,会有更多的判断条件的
FLog.i("HttpLog", "AuthenticatorInterceptor response.code()=" + response.code());
if (response.code() == 400) {
String responseBody = response.body().string();
FLog.i("HttpLog", "AuthenticatorInterceptor responseBody=" + responseBody);
MediaType mediaType;
if (response.body() != null && response.body().contentType() != null) {
mediaType = response.body().contentType();
} else {
mediaType = MediaType.parse("application/json;charset=utf-8");
}
FLog.i("HttpLog", "AuthenticatorInterceptor MediaType=" + mediaType.toString());
FResult fResult = new Gson().fromJson(responseBody, FResult.class);
//response.body().string() 只能调用一次 就会close 所以要重建response
response = response.newBuilder()
.body(ResponseBody.create(mediaType, responseBody))
.build();
if (fResult.getStatus().equals("4001")) {
// 这里应该调用自己的刷新token的接口
// 这里发起的请求是同步的,刷新完成token后再增加到header中
// 这里抛出的错误会直接回调 onError
String token = refreshToken();
if (!TextUtils.isEmpty(token)) {
// 创建新的请求,并增加header
Request retryRequest = chain.request()
.newBuilder()
.header("Authorization", getToken())
.build();
// 再次发起请求
return chain.proceed(retryRequest);
}
}
}
return response;
}
private String refreshToken() {
String newtoken = null;
/**
* 必须使用同步请求
*/
MediaType JSON = MediaType.parse("application/json;charset=utf-8");
Log.e("OkHttpManager", "重新请求---" + url);
OkHttpClient client = new OkHttpClient();
Map<String, String> map = new HashMap<>();
map.put("accessToken", getToken());
map.put("refreshToken", getRefreshToken());
JSONObject jsonObject = new JSONObject(map);
RequestBody requestBody = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder().url(url).post(requestBody).build();
okhttp3.Call call = client.newCall(request);
try {
Response response = call.execute();
// FLog.i("HttpLog", "refreshToken response=" + response.body().string());//只能有效调用一次,不能打印
CredentialDTO credentialDTO = new Gson().fromJson(response.body().string(), CredentialDTO.class);
if (null != credentialDTO.accessToken && null != credentialDTO.refreshToken) {
newtoken = credentialDTO.accessToken;
TokenManager.getInstance().setAccessToken(credentialDTO.accessToken);
TokenManager.getInstance().setRefreshToken(credentialDTO.refreshToken);
FLog.i("HttpLog", "refreshToken accessToken==" + credentialDTO.accessToken);
} else {
newtoken = "";
}
} catch (IOException e) {
e.printStackTrace();
newtoken = "";
}
return newtoken;
}
private String getToken() {
return TokenManager.getInstance().getAccessToken();
}
private String getRefreshToken() {
return TokenManager.getInstance().getRefreshToken();
}
}
调用
//刷新token
builder.addInterceptor(new AuthenticatorInterceptor(mBuilder.mBaseUrl));