Retrofit 2从基础URL中删除主机名后的字符

159

我正在使用 Retrofit 访问一个 RESTful API。基本 URL 为:

http://api.example.com/service

这是接口的代码:

public interface ExampleService {
    @Headers("Accept: Application/JSON")
    @POST("/album/featured-albums")
    Call<List<Album>> listFeaturedAlbums();
}

这是我发送请求并接收响应的方式:

new AsyncTask<Void, Void, Response<List<Album>>>() {

        @Override
        protected Response<List<Album>> doInBackground(Void... params) {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://api.example.com/service")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

            ExampleService service = retrofit.create(ExampleService.class);

            try {
                return service.listFeaturedAlbums().execute();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Response<List<Album>> listCall) {
            Log.v("Example", listCall.raw().toString());
        }
    }.execute();

我得到的日志是奇怪的东西:

V/Example﹕ Response{protocol=http/1.1, code=404, message=Not Found, url=http://api.example.com/album/featured-albums}

这里发生了什么?


你能解决这个问题吗?因为我也遇到了同样的问题。即使我尝试了正确的答案,我仍然无法成功。 - Parth Anjaria
1个回答

368

Retrofit 2使用与HTML中的<a href="">相同的规则。

在你的相对URL开头加上/告诉Retrofit这是主机上的绝对路径。以下是我演示时展示的一个示例:

enter image description here

请注意底部解析出的不正确的URL。

通过移除前导/,URL变为相对路径,并将与基本URL的路径段组合。在修正后的演示中,最终URL现在是正确的:

enter image description here

在您的示例中,基本URL没有尾随的/。 您可能想要添加一个,以便相对路径解析在其之上而不是作为其同级。


27
我不太明白为什么这种新类型的URL解析更有益。它唯一能带来的是隐藏错误(就像这个问题所示),以及反直觉的结果(例如 http://api.example.com/service + /album/featured-albums 不等于 http://api.example.com/album/featured-albums)。而这种沉默的错误只是源于你是将 / 放在基础URL的末尾还是API URL的前面。是否存在任何使用情况使得这种缩短很有用? - EpicPandaForce
4
这是演示的视频链接:https://youtu.be/KIAoQbAu3eA?t=32m19s。 - Albert Vila Calvo
12
看完演示后我理解了,但在网站上添加一个小注释会更好。我花了几分钟才找到问题所在。 - Albert Vila Calvo
9
如何在不添加任何路径段的情况下向baseUrl提交@POST请求?例如:baseUrl为http://api.example.com/album/featured-albums,我希望我的@POST调用与http://api.example.com/album/featured-albums(与baseUrl相同的URL)进行通信。@POST("") 会抛出java.lang.IllegalArgumentException: Missing either @POST URL or @Url parameter.错误。 - ZakTaccardi
18
使用 @Post(".") - Jake Wharton
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接