OKhttp 拦截器Intercept token失效验证

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yrmao9893/article/details/70436940

转载请说明出处:

前言:我相信现在很多人都在用OKhttp作为网络请求库,为什么OKhttp会受到这么多人的青睐呢,谷歌也不例外(据我了解到它是唯一一个被谷歌认可的第三方网络请求库),

原因有很多,对于我来说,OKhttp对我最受用的是它的拦截器机制

拦截器的分类: 

                    1.网络拦截器

                    2.应用拦截器

               借鉴文章: http://www.jianshu.com/p/2710ed1e6b48,对两种拦截器的详细介绍

终于开始文章的主题了:

   原理:利用应用拦截器对请求进行拦截,重定向

   步骤:1.发起一个网络请求,拦截到响应结果

              2.判断响应结果是否为token失效

              3.如果token失效,获取新的token     

              4.携带新的token,重新请求

  好了大概步骤已经梳理好了,判断token失效的方法是什么呢?

 大概有两种:

                              1.http code 标记一个不为200的code(与服务器商定好的:比如当返回的code值为201则表示token失效)

                              2.在响应数据的data里面例如:{"requestStatus":{"code":42441,"msg":"token失效请重新登录","timestamp":1492847318460},"data":""}

到了这里那我们开始吧:

 第一种的验证方法:

public static void tokenInterceptor1(){
        new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                //拿到请求体,并添加header携带上token
                Request mRequest = chain.request().newBuilder()
                        .addHeader("Token", Token)
                        .build();
                //拿到响应体
                Response mResponse = chain.proceed(mRequest);
                //假设返回的code为201时表示token失效
                if (mResponse.code()==201){
                    //重新获取新token
                    //这用了一个特殊接口来获取新的Token
                    Call<String> call = RetrofitFactory.getInstence().API().loginByToken("123456", Token);
                    //拿到请求体
                    Request tokenRequest = call.request();
                    //获取响应体
                    Response tokenResponse = chain.proceed(tokenRequest);
                    //我这假设新的token是在header里返回的
                    //我们拿到新的token头
                    List<String> listHeader = tokenResponse.headers().values("Token");
                    if (listHeader != null) {
                        //重新赋值到新的token
                        Token = listHeader.get(0);
                    }

                    //这是只需要替换掉之前的token重新请求接口就行了
                    Request newRequest = mRequest.newBuilder()
                            .header("Token", Token)
                            .build();
                    return chain.proceed(newRequest);
                }
                return mResponse;
            }
        };
    }

第二种的方法


    public static Interceptor tokeInterceptor2() {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                /**
                 * 1.拦截到返回的数据
                 * 2.判断token是否失效
                 * 3.失效获取新的token
                 * 4.重新请求接口
                 */

                //拿到请求体,并添加header携带上token
                Request mRequest = chain.request().newBuilder()
                        .addHeader("Token", Token)
                        .build();
                //拿到响应体
                Response mResponse = chain.proceed(mRequest);
                ResponseBody responseBody = mResponse.body();

                //得到缓冲源
                BufferedSource source = responseBody.source();

                //请求全部
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                Buffer buffer = source.buffer();
                Charset charset = UTF8;

                MediaType contentType = responseBody.contentType();

                if (contentType != null) {
                    charset = contentType.charset(UTF8);
                }
                //读取返回数据
                String bodyString = buffer.clone().readString(charset);
                if (bodyString != null) {
                    //处理返回的数据我这创建了一个BaseEntity来将数据转化为对象
                    BaseEntity bean = JSON.parseObject(bodyString, BaseEntity.class);
                    //假设当返回的code为42444时token失效
                    if (bean.getCode() == 42444) {
                        //重新获取新token
                        //这用了一个特殊接口来获取新的Token
                        Call<String> call = RetrofitFactory.getInstence().API().loginByToken("123456", Token);
                        //拿到请求体
                        Request tokenRequest = call.request();
                        //获取响应体
                        Response tokenResponse = chain.proceed(tokenRequest);
                        //我这假设新的token是在header里返回的
                        //我们拿到新的token头
                        List<String> listHeader = tokenResponse.headers().values("Token");
                        if (listHeader != null) {
                            //重新赋值到新的token
                            Token = listHeader.get(0);
                        }

                        //这是只需要替换掉之前的token重新请求接口就行了
                        Request newRequest = mRequest.newBuilder()
                                .header("Token", Token)
                                .build();
                        return chain.proceed(newRequest);
                    }
                }

                return chain.proceed(mRequest);
            }
        };

    }


最后贴一个实体类BaseEntity


public class BaseEntity<T> {
    private static int SUCCESS_CODE=42440;//成功的code
    private int code;
    private String msg;
    private T data;


    public boolean isSuccess(){
        return getCode()==SUCCESS_CODE;
    }
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }





}







猜你喜欢

转载自blog.csdn.net/yrmao9893/article/details/70436940