Обновите путь @url с другими параметрами пути

#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",