#android #retrofit2
Вопрос:
Android - retrofit 2.9.0
У меня есть следующий метод модернизации. Я использую @Url, чтобы включить базовый URL-адрес и путь для поиска продуктов. Однако мне нужно пройти a 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: Maplt;String, Stringgt;, @HeaderMap headerMap: Maplt;String, Stringgt; = emptyMap() ): Singlelt;Productsgt;
Комментарии:
1. Для этого существуют функции замены строк.
2. Можете ли вы объяснить, почему вы просто не используете функцию замены строки? Мне довольно неясно, что еще может понадобиться. Можете ли вы сказать, как будет выглядеть URL-адрес результата?
Ответ №1:
То , что вы пытаетесь, не сработает, потому что, если вы укажете @Url
, что он ожидает статический URL-адрес, он не будет принят @Path
во внимание.
Решение 1
Удалите @Path
параметр и просто отправьте отформатированную строку @Url
.
ваше объявление метода будет выглядеть следующим образом:
@GET fun searchProductV2( @Url fullPath: String, @Query("searchCriteria[pageSize]") pageSize: String, @QueryMap apiSearchCriteria: Maplt;String, Stringgt;, @HeaderMap headerMap: Maplt;String, Stringgt; = emptyMap() ): Singlelt;Productsgt;
и ваш 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: Maplt;String, Stringgt;, @HeaderMap headerMap: Maplt;String, Stringgt; = emptyMap() ): Singlelt;Productsgt;
и ваш fullPath
параметр может быть инициализирован следующим образом:
val fullPath = Uri.parse("https://myBaseUrl/v2/products/%s/search".format("storeCode"))
Чтобы сделать этот код более приятным, вы можете создать вспомогательный класс:
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()
Ответ №2:
Определите шаблон URL-адреса с @GET
аннотацией
… а затем замените @Path
аннотацией:
@GET("{baseUrl}products/{storeCode}/search") fun searchProductV2( @Path("baseUrl") baseUrl: String = "https://myBaseUrl/v2/", @Path("storeCode") storeCode: String = "default", ... ): Singlelt;Productsgt;
Там также возможна передача постоянного значения:
@GET(Constants.API_BASE_URL_V2 "products/{storeCode}/search") fun searchProductV2( @Path("storeCode") storeCode: String = "default", ... ): Singlelt;Productsgt;
Или просто версия v2
, предполагающая наличие BASE_URL
https://myBaseUrl/
. Независимо от того, как они объединяются , это должно быть a String
, постоянное значение или a @Path
, больше ничего не допускается:
@GET(Constants.API_VERSION_V2 "/products/{storeCode}/search") fun searchProductV2( @Path("storeCode") storeCode: String = "default", ... ): Singlelt;Productsgt;
Вообще говоря, другого пути нет. Это связано с тем, что ни один параметр не может быть использован в качестве замены другого параметра. Этот код не запускается, а является только interface
определением, из которого создаются соответствующие классы среды выполнения — вот почему пытаться добавить пользовательский код бессмысленно.
Не уверен, что Singlelt;Productsgt;
это такое, но тип возвращаемого значения по умолчанию (без сопоставления / необработанный) будет Calllt;ResponseBodygt;
в Java. Класс/классы модели, используемые для ORM (с конвертером GSON или Moshi), могут использоваться @SerializedName()
для сопоставления имен полей.
Комментарии:
1. если вы рассматриваете базовый URL-адрес как путь, то также будет использоваться базовый URL-адрес, который вы установили во время инициализации модернизации, поэтому базовый URL-адрес будет добавлен дважды.
Ответ №3:
Кажется очевидным и простым решением…
@Url fullPath: String = "https://myBaseUrl/v2/products/" storeCode "/search",