美文网首页
请求失败重新获取token后再次请求

请求失败重新获取token后再次请求

作者: 陈科比大宝贝儿 | 来源:发表于2020-05-25 14:41 被阅读0次

    一般前台和后台交互会用到token,token有一定的时效性,过期之后需要客户端重新请求新的token。
    一般token过期后,和后台沟通后,有以下几种解决方式。
    1.获取到token过期后,跳转到登录界面,这种方式比较简单。
    2.获取到token过期后,在拦截器中拦截到token过期code,然后重新获取token后,放到http头部,然后重新构建request继续请求接口,也比较简单。
    3.第三种方式是在拦截器中重新获取到Token后,把token放到http请求体中,因为还涉及到之前请求体中数据的封装,还有请求方式的不同,所以比较复杂。

    1、如果是get请求:
    请求体在请求url后边,拿出来之后,拼接新的token,重新请求

    1、 Request request = chain.request();//请求对象
        Response response = chain.proceed(request);//响应对象
    2、//获取请求的Url
       HttpUrl url = request.url();
       //循环取出url中?后的参数
      String key = chain.request().url().queryParameterName(i);
      String value = chain.request().url().queryParameterValue(i);
     将这些参数和新的token重新拼接到url的后面
    3、  获取新的request
         return request.newBuilder().url(newUrl).build();
    4、 return chain.proceed(request);
    

    2、如果是post请求:

    如果是表单方式的post请求
    1、 RequestBody body = request.body();
    2、将请求体转换成form表单的形式:
       FormBody formBody = (FormBody) body;
    3、重新获取form表单中的请求参数后,重新构建新的form表单
        FormBody.Builder builder = new FormBody.Builder();
       builder.add(formBody.name(i), formBody.value(i));
      builder.add("token", mNewToken);
    4、  获取新的request
       formBody = builder.build();
             return request.newBuilder()
                           .post(formBody)
                           .build();
    
    

    3、如果是post请求中的json数据

    1、需要获取到之前的请求的json原数据
     RequestBody body = request.body();
     Buffer buffer = new Buffer();
     body.writeTo(buffer);
     String oldParams = buffer.readUtf8(); //读取 传入的 json 字符串
    2、在原始json中拼接新的token
      rootMap.put("token", mNewToken);
     String newJsonParams = new Gson().toJson(rootMap);
    3、返回新的request
     MediaType mediatype= MediaType.parse("application/json; charset=utf-8");
     return request.newBuilder()
                             .post(RequestBody.create(mediatype, newJsonParams))
                              .build();
    

    注意:

    获取新的token一定要用同步请求的方式:

    获取的后台返回的json字符串有两种方式
    response.body().string():只能打印一次
    
    //使用第二种方式:
    ResponseBody responseBody = response.body();
                //解决response.body().string();只能打印一次
                BufferedSource source = responseBody.source();
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                Buffer bufferSlove = source.buffer();
                Charset UTF8 = StandardCharsets.UTF_8;
                //获取后台返回的json字符串
                String string = bufferSlove.clone().readString(UTF8);
    
    

    针对第三种情况,拦截器全部如下:

    
    public class TokenNewInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();//请求对象
            Response response = chain.proceed(request);//响应对象
    
            if (!request.url().toString().contains("get/router/token")){
                //请求对象
                ResponseBody responseBody = response.body();
                //解决response.body().string();只能打印一次
                BufferedSource source = responseBody.source();
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                Buffer bufferSlove = source.buffer();
                Charset UTF8 = StandardCharsets.UTF_8;
                //获取后台返回的json字符串
                String string = bufferSlove.clone().readString(UTF8);
    
                BaseResponse requestCode = new Gson().fromJson(string, BaseResponse.class);
                if (requestCode.isTokenInvalid()) {
                    Logger.d("TokenNewInterceptor:Token登录过期了");
                    Call<BaseResponse<SignData>> tokenCall = GetTokenUtil.INSTANCE.getTokenCall(App.INSTANCE.getContext());
                    BaseResponse<SignData> body = tokenCall.clone().execute().body();
                    request = dealToken(request, chain,body.sign__data.getToken_api());
                    return chain.proceed(request);
                } else {
                    Logger.d("TokenNewInterceptor:Token登录没有过期");
                }
            }
            return response;
        }
        private Request dealToken(Request request, Chain chain, String mNewToken) {
    
            Logger.d("处理token的url:" + request.url().toString());
            UserManager.getInstance().saveToken(mNewToken);
            if ("GET".equals(request.method())) {  //GET请求
                //获取请求的Url
                HttpUrl url = request.url();
                Logger.d("TokenNewInterceptor拦截get:旧的url形式:" + url);
                // HashMap<String, String> params = new HashMap<>();
                HashMap<String, String> oldParams = new HashMap<>();
                for (int i = 0; i < chain.request().url().querySize(); i++) {
                    //取出url中?后的参数
                    String key = chain.request().url().queryParameterName(i);
                    String value = chain.request().url().queryParameterValue(i);
                    oldParams.put(key, value);
                }
                oldParams.put("token", mNewToken); //重新组装的参数
                String newUrl = url.toString();
                int index = newUrl.indexOf("?");
                if (index > 0) {
                    newUrl = newUrl.substring(0, index);
                }
                newUrl = newUrl + "?" + CommonUtil.map2Form(oldParams);
                Logger.d("TokenNewInterceptor拦截get:新的url形式:" + newUrl);
                return request.newBuilder().url(newUrl).build();
            } else {
                RequestBody body = request.body();
                HashMap<String, Object> rootMap = new HashMap<>();
                if (body instanceof FormBody) {//表单数据
                    FormBody formBody = (FormBody) body;
                    FormBody.Builder builder = new FormBody.Builder();
                    int size = formBody.size();
                    //  传入的FormBody 内容
                    for (int i = 0; i < size; i++) {
                        builder.add(formBody.name(i), formBody.value(i));
                    }
                    builder.add("token", mNewToken);
    
                    formBody = builder.build();
                    return request.newBuilder()
                            .post(formBody)
                            .build();
    
                } else {// post 的Json 数据
                    try {
                        Buffer buffer = new Buffer();
                        body.writeTo(buffer);
                        String oldParams = buffer.readUtf8(); //读取 传入的 json 字符串
                        if (oldParams != null) {
                            //拼接参数
                            Logger.d("TokenNewInterceptor拦截postjson:旧的json形式:" + oldParams);
                            rootMap = new Gson().fromJson(oldParams, HashMap.class);
                            rootMap.put("token", mNewToken);
                            String newJsonParams = new Gson().toJson(rootMap);
                            Logger.d("TokenNewInterceptor拦截postjson:新的json形式:" + newJsonParams);
                            MediaType JSON = MediaType.parse("application/json; charset=utf-8");
                            return request.newBuilder()
                                    .post(RequestBody.create(JSON, newJsonParams))
                                    .build();
                        } else {
                            return request;
                        }
                    } catch (Exception e) {
                        return request;
                    }
                }
    
            }
        }
    
    }
    

    相关文章

      网友评论

          本文标题:请求失败重新获取token后再次请求

          本文链接:https://www.haomeiwen.com/subject/dcpeahtx.html