专栏首页刘晓杰okhttp拦截器的使用------修改baseurl

okhttp拦截器的使用------修改baseurl

有的时候做项目的时候会遇到调用接口的url和之前接口定义的url不一样,很可能连retrofit已经设置好的baseurl都要换,但是retrofit并没有提供修改baseurl的方法。那我们只能通过别的方式,比如通过拦截器修改baseurl

public class MainActivity extends AppCompatActivity {

    private static String BASE_URL = "https://api.github.com/";
    private static String BASE_URL_SINGLE = "http://news-at.zhihu.com/";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)

                .addConverterFactory(GsonConverterFactory.create())
                .build();

        final GitHubService repo = retrofit.create(GitHubService.class);


        ((TextView) findViewById(R.id.tv1)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Call<List<Contributor>> call = repo.contributorsByAddConverterGetCall("square", "retrofit");
                call.enqueue(new Callback<List<Contributor>>() {
                    @Override
                    public void onResponse(Call<List<Contributor>> call, retrofit2.Response<List<Contributor>> response) {
                        List<Contributor> contributorList = response.body();
                        if (contributorList != null) {
                            for (Contributor contributor : contributorList) {
                                Log.e("login", contributor.getLogin());
                                Log.e("contributions", contributor.getContributions() + "");
                            }
                        }
                    }

                    @Override
                    public void onFailure(Call<List<Contributor>> call, Throwable t) {

                    }
                });
            }
        });

        ((TextView) findViewById(R.id.tv2)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Call<News> call = repo.getRequest();
                call.enqueue(new Callback<News>() {
                    @Override
                    public void onResponse(Call<News> call, retrofit2.Response<News> response) {
                        News news = response.body();
                        if (news != null) {
                            Log.e("date", news.getDate());
                            for (News.Story story : news.getStories()) {
                                Log.e("story", story.toString());
                            }
                        }
                    }

                    @Override
                    public void onFailure(Call<News> call, Throwable t) {
                        Log.e("onFailure", "onFailure");
                    }
                });
            }
        });
    }
}

service的代码

public interface GitHubService {
    @GET("repos/{owner}/{repo}/contributors")
    Call<List<Contributor>> contributorsByAddConverterGetCall(@Path("owner") String owner, @Path("repo") String repo);

    @GET("api/4/news/latest")
    Call<News> getRequest();//从服务器端过滤数据,获取传入变量对应的数据
}

这是两个联网请求。因为baseurl不一致导致第二个textview点击以后请求出错。我们的目的就是要修改bseurl来让请求成功

第一步

在请求url上添加请求头headers

    @Headers({"baseurl:user"})//其实这里添加什么都无所谓的,主要是为了在拦截器里面捕捉到添加的headers
    @GET("api/4/news/latest")
    Call<News> getRequest();//从服务器端过滤数据,获取传入变量对应的数据

第二步

添加拦截器,捕捉到配置过的headers,然后再修改baseurl

    class ChangeUrlIntercept implements Interceptor {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            //获取request
            Request request = chain.request();

            //获取request的创建者builder
            Request.Builder builder = request.newBuilder();

            //从request中获取headers,通过给定的键url_name
            List<String> headerValues = request.headers("baseurl");
            if (headerValues != null && headerValues.size() > 0) {
                //如果有这个header,先将配置的header删除,因此header仅用作app和okhttp之间使用
                builder.removeHeader("baseurl");

                //从request中获取原有的HttpUrl实例oldHttpUrl
                HttpUrl oldHttpUrl = request.url();

                //匹配获得新的BaseUrl
                String headerValue = headerValues.get(0);
                HttpUrl newBaseUrl = null;
                if ("user".equals(headerValue)) {
                    newBaseUrl = HttpUrl.parse(BASE_URL_SINGLE);
                } else {
                    newBaseUrl = oldHttpUrl;
                }

                //重建新的HttpUrl,修改需要修改的url部分
                HttpUrl newFullUrl = oldHttpUrl
                        .newBuilder()
                        .scheme(newBaseUrl.scheme())
                        .host(newBaseUrl.host())
                        .port(newBaseUrl.port())
                        .build();

                //重建这个request,通过builder.url(newFullUrl).build();
                //然后返回一个response至此结束修改
                return chain.proceed(builder.url(newFullUrl).build());
            } else {
                return chain.proceed(request);
            }
        }

好了,这样只要给retrofit重新配置上这个okhhtpclient就可以了

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • retrofit的使用

    提莫队长
  • 再忆RxJava---线程切换

    RxJava已经陆陆续续看了将近两年多了,觉得很有必要重新认识一下。而且最新github上都出了3.0了。重新看一下,一来作为回顾,二来也算是学习一下3.0 ...

    提莫队长
  • 桥接模式详解

    桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。 具体...

    提莫队长
  • 聊聊artemis的CriticalAnalyzerPolicy

    activemq-artemis-2.11.0/artemis-commons/src/main/java/org/apache/activemq/artemi...

    codecraft
  • 聊聊artemis的CriticalAnalyzerPolicy

    activemq-artemis-2.11.0/artemis-commons/src/main/java/org/apache/activemq/artemi...

    codecraft
  • Spring Boot 过滤器的实现

    过滤器是 Java Servlet 规范中定义的,它能够在请求传送给 Servlet 之前,对 ServletRequest 和 ServletResponse...

    水货程序员
  • springmvc3个适配器

    py3study
  • Spring注解驱动

    @ComponentScan:用于对Component进行扫描,里面有包含与排除规则

    晚上没宵夜
  • Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库

        在 .Net Core 2.2中 Microsoft.AspNetCore.App 默认内置了EntityFramework Core 包,所以在使用过...

    梁规晓
  • java之 代理设计模式

    1. 设计一个案例来实现租房功能。分析:在租房的过程中涉及到了3个对象,房东,中介,房客。

    Vincent-yuan

扫码关注云+社区

领取腾讯云代金券