Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
510 views
in Technique[技术] by (71.8m points)

关于使用okhttp请求网络的怪现象,懂得帮我解答一下,谢谢

出现的问题:
1.自定义拦截器ReceivedCookiesInterceptor内不能写 response.body().string(); 否则会返回400,出现json串200但是走 onError的怪现象

2.只有在自定义拦截器ReceivedCookiesInterceptor内添加header才有效

3.ReceivedCookiesInterceptor必须在REWRITE_CACHE_CONTROL_INTERCEPTOR上面,否则会请求异常

            addInterceptor(new ReceivedCookiesInterceptor()) //todo:需要添加请求头,必须在自定义添加header拦截器
            .addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)

下面我写的网络请求封装对象和自定义拦截器:
1.网络请求封装:

public class RxManager {

    private static RxManager INSTANCE;
    private RequestMethod mRequestService;
    private Gson mGson = new Gson();
    //使用cookie保存用户状态
    private MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    private static WeakReference<Activity> mActivity;
    private static final String TAG = "RxManager";

    private RxManager() {
        OkHttpClient okHttpClient = createOkHttpClient();
        Retrofit retrofit = new Retrofit.Builder().baseUrl(RequestUrl.BASE_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(mGson))
//                .addConverterFactory(ResponseConverterFactory.create(mGson))     //处理Rxjava、Retrofit返回json数据解析异常
                .client(okHttpClient)
                .build();
        mRequestService = retrofit.create(RequestMethod.class);
    }

    public static RxManager getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new RxManager();
        }
        return INSTANCE;
    }

    private OkHttpClient createOkHttpClient() {
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); //这行必须加 不然默认不打印
        //cache url
        File httpCacheDirectory = new File(BaseApplication.getContext().getCacheDir(), "responses");
        int cacheSize = 10 * 1024 * 1024; // 10 MiB
        Cache cache = new Cache(httpCacheDirectory, cacheSize);

        return new OkHttpClient
                .Builder()
//                .cookieJar(cookieJar)    //使用cookie保存用户状态
                .cache(new Cache(BaseApplication.getContext().getCacheDir(), 1024 * 1024 * 100))
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .addInterceptor(loggingInterceptor)     //添加控制台网络请求消息拦截器,直接在控制台输出
                .cache(cache)
                .addInterceptor(new ReceivedCookiesInterceptor()) //todo:需要添加请求头,必须在自定义添加header拦截器
                .addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
//                .addInterceptor(new AddCookiesInterceptor()) //非首次请求
                .addInterceptor(chain -> {
                    Request request = chain.request();
                    Response response = chain.proceed(request);
//                    List<String> values = response.headers().values("Set-Cookie");
//                    Log.d(TAG, "createOkHttpClient: 1512= "+values.size());
//                    for (int i = 0; i < values.size(); i++) {
//                        String s = values.get(i);
//                        Log.d(TAG, "createOkHttpClient: 1512= "+s);
//                    }
//                    int code = response.code();
//                    LogUtils.d("1441  "+code);

//                    String json = response.body().string();
//                    LogUtils.d("1035  "+json);

                    return response;
                }).build();
    }

    //cache
    Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = chain -> {
        CacheControl.Builder cacheBuilder = new CacheControl.Builder();
        cacheBuilder.maxAge(0, TimeUnit.SECONDS);
        cacheBuilder.maxStale(365, TimeUnit.DAYS);
        CacheControl cacheControl = cacheBuilder.build();
        Request request = chain.request();
        if (!NetWorkStatusUtil.checkNetWorkAvaliable(BaseApplication.getContext())) {
            request = request.newBuilder()
                    .cacheControl(cacheControl)
                    .build();
        }
        Response response = chain.proceed(request);
        int code = response.code();
        Request.Builder builder = request.newBuilder();
        //0525   添加请求头
//        builder.addHeader("Content-Type", "application/json");
//        builder.addHeader("Accept", "application/json");
//        builder.addHeader("source", "android");
//        String token = UserManager.getInstance().getToken();
//        if (token != null && !TextUtils.isEmpty(token)) {
//            builder.addHeader("token", token);
//            LogUtils.d("1704  token不为空"+token);
//        } else {
//            LogUtils.d("1704  token为空");
//        }

        //todo:只要是200,这里的代码就不能写 response.body().string();  否则会返回400,出现json串200但是走 onError的怪现象 (问题查找中)
        //todo:不能在 createOkHttpClient 内添加自定义拦截器

//        LogUtils.d("1042  " + code);
        // 1111  拦截器先走,后走onError
        if (code != 200) {
            String json = response.body().string();
            if (!TextUtils.isEmpty(json) && json != null) {
                //todo:传递返回的json数据到onError处理
                //采用全局map传递数据
                BaseApplication.getApplication().getMap().put("json", json);//传递json数据到RxCallback的 onError处理
            }
        }

        // 302直接到未登录主页
//        LogUtils.d("1041    "+response.body().string());


        if (NetWorkStatusUtil.checkNetWorkAvaliable(BaseApplication.getContext())) {
            int maxAge = 0; // read from cache
            return response.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public ,max-age=" + maxAge)
                    .build();
        } else {
            int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
            return response.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .build();
        }
    };

    private RequestMethod getRequestMethod() {
        return mRequestService;
    }

    public static RequestMethod getMethod() {
        return getInstance().getRequestMethod();
    }

    public static RequestMethod getMethod(Activity activity) {
        mActivity = new WeakReference<>(activity);
        return getInstance().getRequestMethod();
    }
    }

2.自定义拦截器

public class ReceivedCookiesInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        //todo:获取已经保存的token
        Request.Builder builder = chain.request().newBuilder();
        builder.addHeader("Content-Type", "application/json");
        builder.addHeader("Accept", "application/json");
        builder.addHeader("source", "android");
        String token = UserManager.getInstance().getToken();
        if (token != null && !TextUtils.isEmpty(token)) {
            builder.addHeader("token", token);
            LogUtils.d("1704  token不为空");
        } else {
            LogUtils.d("1704  token为空");
        }

        // 1111  拦截器先走,后走onError
//        Request request = chain.request();
//        Response response = chain.proceed(request);
//        int code = response.code();

        //todo:只要是200,这里的代码就不能写 response.body().string();  否则会返回400,出现json串200但是走 onError的怪现象 (问题查找中)
//        if (code != 200) {
//            String json = response.body().string();
//            if (!TextUtils.isEmpty(json) && json != null) {
////                //todo:传递返回的json数据到onError处理
////                //采用全局map传递数据
//                BaseApplication.getApplication().getMap().put("json", json);//传递json数据到RxCallback的 onError处理
//            }
//        }
        return chain.proceed(builder.build());
    }

//    @Override
//    public Response intercept(Chain chain) throws IOException {
//        Response originalResponse = chain.proceed(chain.request());
//        if (!originalResponse.headers("Set-Cookie").isEmpty()) {
//            HashSet<String> cookies = new HashSet<>();
//            for (String header : originalResponse.headers("Set-Cookie")) {
//                cookies.add(header);
//                Log.v("OkHttp", "1447   22222Adding Header: " + header);
//            }
//            SharedPreferences.Editor config = BaseApplication.getContext().getSharedPreferences("config", BaseApplication.getContext().MODE_PRIVATE)
//                    .edit();
//            config.putStringSet("cookie", cookies); //保存cookie
//            config.commit();
//        }
//        return originalResponse;
//    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...