Модификация - несколько параметров запроса с тем же именем, где имя задается динамически - PullRequest
0 голосов
/ 25 октября 2018

Я пытаюсь перенести старый проект в библиотеку Retrofit, и у этого проекта довольно сложный API.Итак, у меня есть шаблон запроса, подобный следующему:

@GET(value = "products/search")
Single<ProductSearchResponse> productSearch();

И я должен добавить здесь несколько параметров следующего шаблона:

filter[attributeId]=attributeValueId

Например:

products/search?filter[1]=10&filter[1]=11&filter[2]=20&filter[2]=21

Так работает API, и я не могу его изменить.Я знаю, что мы можем передать список в качестве параметра, например, так:

@Query("filter") List<Integer> attributeValueIds

Но как я могу также динамически установить имя параметра?

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Благодаря ссылке, опубликованной @ILLIA DEREVIANKO (https://github.com/square/retrofit/issues/1324), Мне удалось решить проблему с этим классом:

   public class ProxyRetrofitQueryMap extends HashMap<String, Object> {
    public ProxyRetrofitQueryMap(Map<String, Object> m) {
        super(m);
    }

    @Override
    public Set<Entry<String, Object>> entrySet() {
        Set<Entry<String, Object>> originSet = super.entrySet();
        Set<Entry<String, Object>> newSet = new HashSet<>();

        for (Entry<String, Object> entry : originSet) {
            String entryKey = entry.getKey();
            if (entryKey == null) {
                throw new IllegalArgumentException("Query map contained null key.");
            }
            Object entryValue = entry.getValue();
            if (entryValue == null) {
                throw new IllegalArgumentException(
                        "Query map contained null value for key '" + entryKey + "'.");
            }
            else if(entryValue instanceof List) {
                for(Object arrayValue:(List)entryValue)  {
                    if (arrayValue != null) { // Skip null values
                        Entry<String, Object> newEntry = new AbstractMap.SimpleEntry<>(entryKey, arrayValue);
                        newSet.add(newEntry);
                    }
                }
            }
            else {
                Entry<String, Object> newEntry = new AbstractMap.SimpleEntry<>(entryKey, entryValue);
                newSet.add(newEntry);
            }
        }
        return newSet;
    }
}

С этим мы можем просто использовать карту,где ключ - это уникальное имя параметра, а значение - список строк, которые являются значениями для этого параметра. Примерно так:

ProxyRetrofitQueryMap map = new ProxyRetrofitQueryMap();

    List<String> values1 = new ArrayList<>();
    values1.add("10");
    values1.add("11");
    map.put("filter[1]", values1);

    List<String> values2 = new ArrayList<>();
    values1.add("20");
    values1.add("21");
    map.put("filter[2]", values2);
0 голосов
/ 25 октября 2018

Вы можете использовать аннотацию @QueryMap следующим образом:

public interface NewsService() {  
    @GET("/news")
    Call<List<News>> getNews(
        @QueryMap Map<String, String> options
    );
}

Map<String, String> data = new HashMap<>();
data.put("author", "Marcus");
data.put("page", String.valueOf(2));

...
newsService.getNews(data);

Подробнее: https://futurestud.io/tutorials/retrofit-2-add-multiple-query-parameter-with-querymap

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...