有一个类似的问题问在这里,但我的情况有点不同.
我正在尝试提出类似以下的请求:
http://www.example.com/abc?foo=def&foo=ghi&foo=jkl&bar=xyz
我有两个问题让事情变得困难.首先,重复参数("foo"多次设置值)阻止使用QueryMap(我没有选项以不同的方式传递查询字符串中的值,就像数组一样).其次,我正在使用的查询参数是动态的,所以我不能真正使用Query并为它提供给定参数名称的值列表,因为在我发出请求之前我不会知道参数名称.
我试图从升级的代码使用改造的旧版本,但不知何故,它有一个概念QueryList,其采取了List的NameValuePairS IN查询参数传递的名称(及其作为值值),并允许重复的参数.我没有retrofit.http.QueryList在Retrofit的源代码历史记录或网络上看到任何引用,所以我不确定这是否是当时的自定义添加.在任何情况下,我都试图找到在最新版本中复制该功能的最佳方式,所以任何帮助将不胜感激!
Nir*_*raj 18
为了跟进,我能够通过使用QueryMap和一些黑客来解决这个问题.基本上我把我List的NameValuePairs转换成HashMap,在那里我检查我是否已经拥有密钥,如果我这样做,我将相同密钥的新值附加到旧值.所以基本上(键,值)会变成(键,值和键=值2).这样,当构造查询字符串时,我将根据需要使用key = value&key = value2.为了使其工作,我需要自己处理值编码,以便我在值中包含的额外&符号和等号不会被编码.
所以这HashMap是由List这样构造的:
public static HashMap<String, String> getPathMap(List<NameValuePair> params) {
HashMap<String, String> paramMap = new HashMap<>();
String paramValue;
for (NameValuePair paramPair : params) {
if (!TextUtils.isEmpty(paramPair.getName())) {
try {
if (paramMap.containsKey(paramPair.getName())) {
// Add the duplicate key and new value onto the previous value
// so (key, value) will now look like (key, value&key=value2)
// which is a hack to work with Retrofit's QueryMap
paramValue = paramMap.get(paramPair.getName());
paramValue += "&" + paramPair.getName() + "=" + URLEncoder.encode(String.valueOf(paramPair.getValue()), "UTF-8");
} else {
// This is the first value, so directly map it
paramValue = URLEncoder.encode(String.valueOf(paramPair.getValue()), "UTF-8");
}
paramMap.put(paramPair.getName(), paramValue);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
return paramMap;
}
Run Code Online (Sandbox Code Playgroud)
然后我的请求看起来像这样:
@GET("/api/")
List<Repo> listRepos(@QueryMap(encodeValues=false) Map<String, String> params);
Run Code Online (Sandbox Code Playgroud)
我的服务电话看起来像这样:
// Get the list of params for the service call
ArrayList<NameValuePair> paramList = getParams();
// Convert the list into a map and make the call with it
Map<String, String> params = getPathMap(paramList);
List<Repo> repos = service.listRepos(params);
Run Code Online (Sandbox Code Playgroud)
我最初尝试使用Path手动构建查询字符串的解决方案,但查询字符串中不允许使用替换块,因此我使用了此QueryMap解决方案.希望这可以帮助遇到同样问题的其他人!
| 归档时间: |
|
| 查看次数: |
1716 次 |
| 最近记录: |