有的時候做項目的時候會遇到調用接口的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就可以了