Retrofit - 动态设置名称的多个同名查询参数 [英] Retrofit — Multiple query parameters of same name where name is set dynamically

查看:65
本文介绍了Retrofit - 动态设置名称的多个同名查询参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将旧项目迁移到 Retrofit 库,而该项目的 API 非常棘手.所以我有一个这样的查询模板:

I'm trying to migrate an old project to Retrofit library and this project has quite tricky API. So I have a query template like this:

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

我必须在以下模板中添加一些参数:

And I have to add some parameters here of following template:

filter[attributeId]=attributeValueId

例如:

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

API 就是这样工作的,我无法更改它.我知道我们可以将列表作为参数传递,如下所示:

That's how API works and I can't change it. I know that we can pass a list as a parameter, like this:

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

但是我怎样才能动态设置参数的名称呢?

But how can I also set parameter's name dynamically?

推荐答案

感谢@ILLIA DEREVIANKO 发布的链接 (https://github.com/square/retrofit/issues/1324),我已经设法解决了这个类的问题:

Thanks to the link, posted by @ILLIA DEREVIANKO (https://github.com/square/retrofit/issues/1324), I've managed to solve the problem with this class:

   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;
    }
}

有了这个,我们可以只使用一个映射,其中键是唯一的参数名称,值是一个字符串列表,即该参数的值.像这样:

With this we can just use a map, where key is a unique parameter name and value is a List of Strings, that are values for this parameter. Something like this:

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);

这篇关于Retrofit - 动态设置名称的多个同名查询参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆