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就可以了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章