使用不同的路径参数更新@url 路径
Update @url path with different path parameters
Android - retrofit 2.9.0
我有以下改造方法。我正在使用 @Url 来包含基础 url 和搜索产品的路径。但是,我需要将 code
作为路径的一部分传递。因为我需要包含完整路径,所以如何将代码添加到完整的 url 路径中?
"https://myBaseUrl/v2/products/{code}/search"
@GET
fun searchProductV2(
@Path("code") storeCode: String,
@Url fullPath: String = "https://myBaseUrl/v2/products/{code}/search",
@Query("searchCriteria[pageSize]") pageSize: String,
@QueryMap apiSearchCriteria: Map<String, String>,
@HeaderMap headerMap: Map<String, String> = emptyMap()
): Single<Products>
似乎是显而易见且简单的解决方案...
@Url fullPath: String = "https://myBaseUrl/v2/products/" +storeCode+ "/search",
使用 @GET
注释定义 URL 模板
...然后替换为 @Path
注释:
@GET("{baseUrl}products/{storeCode}/search")
fun searchProductV2(
@Path("baseUrl") baseUrl: String = "https://myBaseUrl/v2/",
@Path("storeCode") storeCode: String = "default",
...
): Single<Products>
这里也可以传递常量值:
@GET(Constants.API_BASE_URL_V2 + "products/{storeCode}/search")
fun searchProductV2(
@Path("storeCode") storeCode: String = "default",
...
): Single<Products>
或者只是版本 v2
,假设 BASE_URL
为 https://myBaseUrl/
。无论这些如何组合,都必须是 String
、常量值或 @Path
,不允许其他任何内容:
@GET(Constants.API_VERSION_V2 + "/products/{storeCode}/search")
fun searchProductV2(
@Path("storeCode") storeCode: String = "default",
...
): Single<Products>
总的来说,没有别的办法。这是因为没有参数可以用作另一个参数的替代。此代码不是 运行,而只是 interface
定义,从中生成相应的 运行time 类 - 这就是尝试添加自定义代码的原因毫无意义。
不确定 Single<Products>
是什么,但默认(未映射/原始)return 类型是 Java 中的 Call<ResponseBody>
。用于 ORM 的模型 class/es(带有 GSON 或 Moshi 转换器)可以使用 @SerializedName()
映射字段名称。
您尝试的方法不会起作用,因为如果您指定 @Url
,它需要静态 URL,它不会考虑 @Path
。
解决方案 1
删除@Path
参数,只发送@Url
中的格式化字符串。
您的方法声明将如下所示:
@GET
fun searchProductV2(
@Url fullPath: String,
@Query("searchCriteria[pageSize]") pageSize: String,
@QueryMap apiSearchCriteria: Map<String, String>,
@HeaderMap headerMap: Map<String, String> = emptyMap()
): Single<Products>
你的fullPath
参数可以这样初始化:
val fullPath = "https://myBaseUrl/v2/products/%s/search".format("storeCode")
解决方案 2
更好的方法是不使用String
作为@Url
参数。
(@Url
可以是 okhttp3.HttpUrl
、String
、java.net.URI
或 android.net.Uri
)
这是一个使用 android.net.Uri
的例子:
您的方法声明将如下所示:
@GET
fun searchProductV2(
@Url fullPath: Uri,
@Query("searchCriteria[pageSize]") pageSize: String,
@QueryMap apiSearchCriteria: Map<String, String>,
@HeaderMap headerMap: Map<String, String> = emptyMap()
): Single<Products>
你的fullPath
参数可以这样初始化:
val fullPath = Uri.parse("https://myBaseUrl/v2/products/%s/search".format("storeCode"))
为了让这段代码更漂亮,你可以创建一个助手 class:
class DynamicUrl(private val formatString: String, private vararg val args: Any?) {
fun toUri(): Uri = Uri.parse(formatString.format(*args))
}
现在您的 fullPath
参数可以像这样初始化:
val fullPath = DynamicUrl("https://myBaseUrl/v2/products/%s/search", "storeCode").toUri()
Android - retrofit 2.9.0
我有以下改造方法。我正在使用 @Url 来包含基础 url 和搜索产品的路径。但是,我需要将 code
作为路径的一部分传递。因为我需要包含完整路径,所以如何将代码添加到完整的 url 路径中?
"https://myBaseUrl/v2/products/{code}/search"
@GET
fun searchProductV2(
@Path("code") storeCode: String,
@Url fullPath: String = "https://myBaseUrl/v2/products/{code}/search",
@Query("searchCriteria[pageSize]") pageSize: String,
@QueryMap apiSearchCriteria: Map<String, String>,
@HeaderMap headerMap: Map<String, String> = emptyMap()
): Single<Products>
似乎是显而易见且简单的解决方案...
@Url fullPath: String = "https://myBaseUrl/v2/products/" +storeCode+ "/search",
使用 @GET
注释定义 URL 模板
...然后替换为 @Path
注释:
@GET("{baseUrl}products/{storeCode}/search")
fun searchProductV2(
@Path("baseUrl") baseUrl: String = "https://myBaseUrl/v2/",
@Path("storeCode") storeCode: String = "default",
...
): Single<Products>
这里也可以传递常量值:
@GET(Constants.API_BASE_URL_V2 + "products/{storeCode}/search")
fun searchProductV2(
@Path("storeCode") storeCode: String = "default",
...
): Single<Products>
或者只是版本 v2
,假设 BASE_URL
为 https://myBaseUrl/
。无论这些如何组合,都必须是 String
、常量值或 @Path
,不允许其他任何内容:
@GET(Constants.API_VERSION_V2 + "/products/{storeCode}/search")
fun searchProductV2(
@Path("storeCode") storeCode: String = "default",
...
): Single<Products>
总的来说,没有别的办法。这是因为没有参数可以用作另一个参数的替代。此代码不是 运行,而只是 interface
定义,从中生成相应的 运行time 类 - 这就是尝试添加自定义代码的原因毫无意义。
不确定 Single<Products>
是什么,但默认(未映射/原始)return 类型是 Java 中的 Call<ResponseBody>
。用于 ORM 的模型 class/es(带有 GSON 或 Moshi 转换器)可以使用 @SerializedName()
映射字段名称。
您尝试的方法不会起作用,因为如果您指定 @Url
,它需要静态 URL,它不会考虑 @Path
。
解决方案 1
删除@Path
参数,只发送@Url
中的格式化字符串。
您的方法声明将如下所示:
@GET
fun searchProductV2(
@Url fullPath: String,
@Query("searchCriteria[pageSize]") pageSize: String,
@QueryMap apiSearchCriteria: Map<String, String>,
@HeaderMap headerMap: Map<String, String> = emptyMap()
): Single<Products>
你的fullPath
参数可以这样初始化:
val fullPath = "https://myBaseUrl/v2/products/%s/search".format("storeCode")
解决方案 2
更好的方法是不使用String
作为@Url
参数。
(@Url
可以是 okhttp3.HttpUrl
、String
、java.net.URI
或 android.net.Uri
)
这是一个使用 android.net.Uri
的例子:
您的方法声明将如下所示:
@GET
fun searchProductV2(
@Url fullPath: Uri,
@Query("searchCriteria[pageSize]") pageSize: String,
@QueryMap apiSearchCriteria: Map<String, String>,
@HeaderMap headerMap: Map<String, String> = emptyMap()
): Single<Products>
你的fullPath
参数可以这样初始化:
val fullPath = Uri.parse("https://myBaseUrl/v2/products/%s/search".format("storeCode"))
为了让这段代码更漂亮,你可以创建一个助手 class:
class DynamicUrl(private val formatString: String, private vararg val args: Any?) {
fun toUri(): Uri = Uri.parse(formatString.format(*args))
}
现在您的 fullPath
参数可以像这样初始化:
val fullPath = DynamicUrl("https://myBaseUrl/v2/products/%s/search", "storeCode").toUri()