Okhttp重定向处理

作者: 慕涵盛华 | 来源:发表于2018-12-04 10:44 被阅读9次

    重定向

    客户端向服务器发送一个请求,获取对应的资源,服务器收到请求后,发现请求的这个资源实际放在另一个位置,于是服务器在返回的响应头的Location字段中写入那个请求资源的正确的URL,并设置reponse的状态码为30x 。

    相关状态码说明

    Okhttp代码中的实现

    RetryAndFollowUpInterceptorintercept方法中构建了while (true)循环,根据response重建requestRequest followUp = followUpRequest(response)

    判断是否需要重定向的逻辑在followUpRequest方法中:

    1.如果响应码是307 或者308并且请求方法不是 GET 或者 HEAD 请求不进行重定向。
    2.重定向的地址从响应头中获取 “Location”。
    3.HTTPS 和 HTTP 之间的重定向,需要根据配置 followSslRedirects 来判断。final boolean followSslRedirects; //安全套接层重定向
    4.如果请求不是PROPFIND的重定向,重定向后的请求会转为GET请求。

    我们项目中的请求大都是POST请求或者GET请求,有时候为了安全考虑,全部都用POST请求,在遇到重定向的时候会被转成GET请求,或者我们的重定向状态码使用的是307,并且请求方法是GET,Okhttp就不支持了。这就不符合我们的要求了。有时候还可能实现跨域重定向,如:HTTP -> HTTPS。

    既然Okhttp默认的实现不能满足我们的要求,就需要我们自己去实现,其实实现很简单,我们只需要自定义一个拦截器,判断重定向的响应码,然后从响应头中获取重定向后的地址,重新请求一遍即可。

    重定向处理

    //处理重定向的拦截器
    public class RedirectInterceptor implements Interceptor {
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            okhttp3.Request request = chain.request();
            Response response = chain.proceed(request);
            int code = response.code();
            if (code == 307) {
                //获取重定向的地址
                String location = response.headers().get("Location");
                LogUtils.e("重定向地址:", "location = " + location);
                //重新构建请求
                Request newRequest = request.newBuilder().url(location).build();
                response = chain.proceed(newRequest);
            }
            return response;
        }
    }
    
     //使用
     OkHttpClient client = new OkHttpClient.Builder()
                        .followRedirects(false);  //禁制OkHttp的重定向操作,我们自己处理重定向
                        .addInterceptor(new RedirectInterceptor())
                        .build();
    

    相关文章

      网友评论

        本文标题:Okhttp重定向处理

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