有的时候做项目的时候会遇到调用接口的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就可以了