android - 为什么 Retrofit 向所有 URL 添加尾部斜杠?

标签 android retrofit

使用更多详细信息编辑问题:

我了解 Retrofit 中服务接口(interface)的使用。我想调用这样的 URL: http://a.com/b/c (然后使用服务接口(interface)附加查询参数)。

我的限制是:

  1. 不能将/b/c 用作服务接口(interface)的一部分(作为路径参数)。我需要它作为基本网址的一部分。我在下面详细说明了原因。

  2. 无法负担得起对http://a.com/b/c/?key=val的结果调用.我需要的是 http://a.com/b/c?key=val (“c”后的尾部斜线为我的 API 带来了问题)。下面有更多详细信息。

我的服务器 API 变化非常频繁,我在客户端使用 Retrofit 时遇到了麻烦。主要问题是我们不能将动态值(非最终值)传递给路径参数的@GET 或@POST 注释(就像查询参数一样)。例如,当 API 更改时,甚至路径参数的数量也会更改。每次 API 更改时,我们都无法承受不同的接口(interface)。

一个解决方法是形成完整的 URL,即具有 Base_Url + Path_Parameters 的端点。

但我想知道为什么 Retrofit 会强制在基本 url 中添加尾部斜杠(“/”):

        String API_URL = "https://api.github.com/repos/square/retrofit/contributors";
        if (API_URL.endsWith("/")) {
            API_URL = API_URL.substring(0, API_URL.length() - 1);
        }
        System.out.println(API_URL);   //prints without trailing "/"

        RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint(API_URL)
        .build();

API_URL 总是重置为 https://api.github.com/repos/square/retrofit/contributors/通过内部改造(通过记录请求确认这一点)

一个解决方法是手动添加“?”最后防止添加“/”:https://api.github.com/repos/square/retrofit/contributors

很遗憾,我们的 API 不会接受此类请求。

  1. 为什么 Retrofit 会强制执行此行为?
  2. 对于像我这样不想要尾部斜杠的人,是否有解决方案?
  3. 我们可以将可变参数(非最终)传递给 Retrofit @GET 或 @POST 注释吗?

最佳答案

您需要将基本 URL 传递给 setEndpoint(...) 并在您的服务接口(interface)中定义 /repos/...

快速演示:

class Contributor {

    String login;

    @Override
    public String toString() {
        return String.format("{login='%s'}", this.login);
    }
}

interface GitHubService {

    @GET("/repos/{organization}/{repository}/contributors")
    List<Contributor> getContributors(@Path("organization") String organization,
                                      @Path("repository") String repository);
}

然后在您的代码中,您可以:

GitHubService service = new RestAdapter.Builder()
        .setEndpoint("https://api.github.com")
        .build()
        .create(GitHubService.class);

List<Contributor> contributors = service.getContributors("square", "retrofit");
System.out.println(contributors);

将打印:

[{login='JakeWharton'}, {login='pforhan'}, {login='edenman'}, {login='eburke'}, {login='swankjesse'}, {login='dnkoutso'}, {login='loganj'}, {login='rcdickerson'}, {login='rjrjr'}, {login='kryali'}, {login='holmes'}, {login='adriancole'}, {login='swanson'}, {login='crazybob'}, {login='danrice-square'}, {login='Turbo87'}, {login='ransombriggs'}, {login='jjNford'}, {login='icastell'}, {login='codebutler'}, {login='koalahamlet'}, {login='austynmahoney'}, {login='mironov-nsk'}, {login='kaiwaldron'}, {login='matthewmichihara'}, {login='nbauernfeind'}, {login='hongrich'}, {login='thuss'}, {login='xian'}, {login='jacobtabak'}]

Can we have variable parameters (non final) being passed to Retrofit @GET or @POST annotations ?

不可以,(Java) 注释中的值必须声明为 final。但是,您可以定义变量路径,正如我在演示中展示的那样。

编辑:

请注意 Jake 在评论中的评论:

Worth noting, the code linked in the original question deals with the case when you pass https://api.github.com/ (note the trailing slash) and it gets joined to /repos/... (note the leading slash). Retrofit forces leading slashes on the relative URL annotation parameters so it de-dupes if there's a trailing slash on the API url.

关于android - 为什么 Retrofit 向所有 URL 添加尾部斜杠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27304174/

相关文章:

java - Retrofit 对象返回为 null

android - 如何模拟 Retrofit Response

java - Android多个activity访问一个java类

android - 非 UI fragment 与单例

java - 干净的滚动方式

android - 改造 2 : responseBodyConverter converts to null object

android - 使用改造和 rx java 的多个 api 请求

android - 在Google Play应用程序中用特殊字符搜索

java - 应用程序关闭时保持 IRC 连接处于 Activity 状态

java - NPE 很难从 logcat 中发现它似乎是 Arraylist 但每个项目都应该设置