Retrofit2为动态url带来的新的注解,在Retrofit 1中迷惑的点现在只需要一个 Url
注解就能描述结点(endpoint)。
这篇文章将会展示如何利用动态结点url处理单独的请求。
原文地址
Retrofit 2 — How to Use Dynamic Urls for Requests
使用案例情况
这里有两个案例来说明真实的应用场景。
- 图片详情:如果你的app允许用户上传他们自己的个人头像,你可能需要将这些文件储存在不同的地方比如你自己的服务器,Amazon S3(亚马逊云服务)或者是Gravatar(Globally Recognized Avatar)
- 文件下载:文件可以被存储在多个地方而且你希望从任何资源地址灵活的下载内容
即使你的app没有任何建议的功能,你也可以可以适当的想象一个适合动态URL使用的例子。
怎么使用动态URLs
实际上,它只需要你加入一个单独的注解 @Url
在你的定义的结点,一图胜千言
public interface UserService {
@GET
public Call<ResponseBody> profilePicture(@Url String url);
}
可以看到,在 GET
上不需要结点url,我们可以直接在方法中去添加这个url
Urls是怎么针对base url解析的
有另外一个有趣而且需要注意的地方:动态url是怎么在已经定义base Url的情况下被解析的,Retrofit 2使用OkHttp的 HttpUrl 而且解析任何URL结点成类似一个网址的链接。
让我们根据一些场景来明白这个过程,首先我们有一个url指向Amazon S3(注:一个云服务平台,类似七牛)中存储的一个图片地址,而且我们也已经定义了一个base Url,这两个的地址是完全不一样的,
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://your.api.url/");
.build();
UserService service = retrofit.create(UserService.class);
service.profilePicture("https://s3.amazon.com/profile-picture/path");
// request url results in:
// https://s3.amazon.com/profile-picture/path
因为你设置了一个完全不同的包含scheme的host (https://s3.amazon.com vs. https://your.api.url) ,OkHttp的HttpUrl会解析它成我们设置的url,这个和我们所定义的base Url并没有关系。
第二个例子:这次我们指定动态url在我们已经定义的base Url同一个服务下面,比如下面的代码
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://your.api.url/");
.build();
UserService service = retrofit.create(UserService.class);
service.profilePicture("profile-picture/path");
// request url results in:
// https://your.api.url/profile-picture/path
这次,这个最终的请求url被会我们定义的base Url和动态结点url联系起来,HttpUrl(OkHttp)会意识到我们没有指定一个scheme和host,因此这个url结点会被加到base Url的后面。
第三个例子:我们假设后端开发发布了一个更新版本v2,并且和原来的base Url冲突了,比如下面的例子
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://your.api.url/v2/");
.build();
UserService service = retrofit.create(UserService.class);
service.profilePicture("/profile-picture/path");
// request url results in:
// https://your.api.url/profile-picture/path
第二和第三个例子的不同点就是:我们添加了一个 v2/
到base url后面并且在结点url的前面添加了一个 /
。实际上这将会最终生成同样的url,因为结点url的前面是一个 /
符号,这个将会只添加到base Url的host上面。当我们在结点url上添加一个前置 /
符号时,每个加到host Url后面的东西都会被省略掉。删除前置 /
有时候可以解决你的一些不明白的问题。
分析提示
正确的“创建”请求url是你需要注意的问题。这些文章中的例子展示了一些容易犯的错误,一不小心就可能陷入这个陷阱中,确保你在请求时使用了一个完全的url(包括scheme,host,path),否则你不得不去考虑上面的这些场景。
网友评论
// https://your.api.url/profile-picture/path应该是https://your.api.url/v2/profile-picture/path吧