Open pawel-kaminski-krk opened 8 years ago
None of the maps support this currently, no.
is there any road map. we solve the issue adding another parameter with @Query annotation which supports multi value. but this is ugly
In my project I serialized my object via GSON to string and with @Query annotation I succeed to send it probably
it is not about serializing but properly handling multivalues for one key
@PartMap
does not support multi values as well. One trick around it is to extend Map
and overriding Map#entrySet()
, though this can break as it depends on the internals.
Most likely #1184 provides some help with this.
thanks! it seems will do the trick!
in the meantime, i hacked this together for anyone who absolutely needs this and can't wait - https://gist.github.com/mandybess/dca2e8a0527aff2d8e0688c17297c945
I have a simple trick.
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;
}
}
and use that class => @Querymap or @FieldMap.
hi, is this supported in the lastest retrofit version ?
@jm-lim's solution, converted for Kotlin:
class ProxyRetrofitQueryMap(m: MutableMap<String, Any>) : HashMap<String, Any>(m) {
override val entries: MutableSet<MutableMap.MutableEntry<String, Any>>
get() {
val originSet: Set<Map.Entry<String?, Any?>> = super.entries
val newSet: MutableSet<MutableMap.MutableEntry<String, Any>> = HashSet()
for ((key, entryValue) in originSet) {
val entryKey = key ?: throw IllegalArgumentException("Query map contained null key.")
// Skip null values
requireNotNull(entryValue) { "Query map contained null value for key '$entryKey'." }
if (entryValue is List<*>) {
for (arrayValue in entryValue) {
if (arrayValue != null) { // Skip null values
val newEntry: MutableMap.MutableEntry<String, Any> =
SimpleEntry(entryKey, arrayValue)
newSet.add(newEntry)
}
}
} else {
val newEntry: MutableMap.MutableEntry<String, Any> = SimpleEntry(entryKey, entryValue)
newSet.add(newEntry)
}
}
return newSet
}
}
Any update on this or should we go with custom solution? @JakeWharton
+1 on this issue. Please support Map<String, Iterable
btw - if your input already has data on the form Map<String, List
private class ProxyRetrofitQueryMap(val original: Map<String, List<String>>) : AbstractMap<String, String>() {
override val entries: Set<Map.Entry<String, String>>
get() {
return original.entries.flatMap { (key, value) -> value.map { SimpleEntry(key, it) } }.toSet()
}
}
hi, we are using retrofit 1.9 and we declared our endpoint as
which works fine and is expanded to ex.
host/path?rq=1&ra=2
for input{"rq": "1", "ra": "2"}
.right now we need to support multivalue same as described here https://futurestud.io/blog/retrofit-multiple-query-parameters-of-same-name but for @QueryMap. and declaring endpoint as
doesn't help at all as value is expanded to its string equivalent ex.
host/path?rq=[1,2]
for input{"rq": ["1", "2"]}
. we would like to get same behavior as for @Query ex.host/path?rq=1&rq=2
for input{"rq": ["1", "2"]}
.is there any work around for now?