OKHTTP加拦截Interceptor 刷新token

在这里插入图片描述

原因为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));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葫芦娃你好我是皮卡丘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值