1. 概述

在本篇短文中,我们将学习如何在 Retrofit 2动态构建请求 URL。这对于需要在运行时根据条件拼接不同接口地址的场景非常有用。

2. 使用 @Url 注解

有些时候我们无法提前确定完整的请求地址,只能在运行时动态传入完整 URL。Retrofit 2 引入了 @Url 注解来支持这种需求,它允许我们为某个接口方法传入一个完整的 URL 地址:

@GET
Call<ResponseBody> reposList(@Url String url);

这个注解基于 OkHttp 库中的 HttpUrl 类实现,其解析规则类似于 HTML 页面中 <a href=""> 标签的行为。

⚠️ 注意:使用 @Url 参数时,不需要在 @GET 等注解中指定路径。

此外,当使用 @Url 时,会覆盖掉 Retrofit 构建时设置的 baseUrl,例如下面这段配置:

Retrofit retrofit = new Retrofit.Builder()
  .baseUrl("https://api.github.com/")
  .addConverterFactory(GsonConverterFactory.create())
  .build();

✅ 小贴士:如果要使用 @Url 注解,请务必把它作为接口方法的第一个参数。

3. 使用 @Path 传递部分路径

如果你知道 base URL 是固定的,但后续路径可能是动态生成的,或者参数个数不确定,那么可以考虑使用 @Path 注解,并配合 encoded = true 参数来避免路径被自动编码:

@GET("{fullUrl}")
Call<List<Contributor>> contributorsList(@Path(value = "fullUrl", encoded = true) String fullUrl);

这样处理后,路径中的 / 字符不会被转义成 %2F(如果不加 encoded = true 则会被转义)。但是要注意,路径中的 ? 仍然会被转义为 %3F

❌ 踩坑提醒:路径中如果包含查询参数(如 ?key=value),建议还是使用 @Query 或者直接拼接到完整 URL 中更稳妥。

4. 总结

通过 Retrofit 提供的 @Url 注解,我们可以非常简单地实现在运行时动态指定请求地址的需求。相比手动拼字符串或封装工具类,这种方式更加优雅且符合 Retrofit 的设计哲学。

本文所有代码示例都可以在 GitHub 上找到:https://github.com/eugenp/tutorials/tree/master/libraries-http-2


原始标题:Retrofit 2 - Dynamic URL