Describe the bug
@SpringQueryMap doesn't support Map
Sample
@FeignClient(name = "postman-echo", url = "https://postman-echo.com")
public interface PostmanEchoClient {
@GetMapping(path = "/get")
Object get(@SpringQueryMap Map<String, String[]> paramMap);
}
Test
Map<String, String[]> paramMap = new HashMap<>(2);
paramMap.put("a", new String[] {"a1", "a2"});
paramMap.put("b", new String[] {"b1", "b2"});
postmanEchoClient.get(paramMap);
Generated url: https://postman-echo.com/get?a=%5BLjava.lang.String%3B%405ed08faf&b=%5BLjava.lang.String%3B%4075386aa2
Expected url: https://postman-echo.com/get?a=a1&a=a2&b=b1&b=b2
Comment From: OLPMO
Has this bug been fixed?@spencergibb And cloud you provide a minimal demo to reproduce this problem? @linianhui
Comment From: OlgaMaciaszek
We've not worked on that yet @OLPMO . Would you like to create a PR?
Comment From: xue8
A key corresponds to a value, so Map <String, String []> does not exist.
Comment From: Junhyunny
Hi, I find out this issue comes from the method which name is "addQueryMapQueryParameters" in ReflectiveFeign class .
link - https://github.com/OpenFeign/feign/blob/master/core/src/main/java/feign/ReflectiveFeign.java
The method only checks Iterable. I think some code should be added like this.
Object currValue = currEntry.getValue();
if (currValue instanceof Iterable<?>) {
Iterator<?> iter = ((Iterable<?>) currValue).iterator();
while (iter.hasNext()) {
Object nextObject = iter.next();
values.add(nextObject == null ? null : encoded ? nextObject.toString() : UriUtils.encode(nextObject.toString()));
}
} else if (currValue instanceof Object[]) {
for (Object nextObject : (Object[]) currValue) {
values.add(nextObject == null ? null : encoded ? nextObject.toString() : UriUtils.encode(nextObject.toString()));
}
} else {
values.add(currValue == null ? null : encoded ? currValue.toString() : UriUtils.encode(currValue.toString()));
}
thanks.
Comment From: spencergibb
@Junhyunny Then an issue should be opened here https://github.com/OpenFeign/feign/issues
Comment From: Junhyunny
@linianhui, here is my example. You can see the result what you want in log when you use List instead of array.
link - https://github.com/Junhyunny/openfeign-test test - curl localhost:8080/testList
@spencergibb I found out other problem in my example. RequestParam is {a=a1, b=b1}. I expect RequestParam {a=[a1, a2], b=[b1,b2]}. What do you think of this? Is it bug?
Comment From: linianhui
@Junhyunny
List can solve my current problem, Thank you for your help.
Comment From: Junhyunny
@spencergibb I found that result comes from "resolveArgument" method in RequestParamMapMethodArgumentResolver class.
(package org.springframework.web.method.annotation)
Map<String, String> result = new LinkedHashMap<>(parameterMap.size());
parameterMap.forEach((key, values) -> {
if (values.length > 0) {
result.put(key, values[0]);
}
});
return result;
Resolver gets only the first value in list. When I look over the code, I think they intentionally made resolver because they predicted values.
Comment From: spencergibb
Closing in favor of https://github.com/OpenFeign/feign/issues/1170