2

I cannot figure out how to pass in a Java List into a Spring RestTemplate call and then use the list in the Controller method

Client code:

public String generateInfoOfIds(List<String> ids, String userName, String password){
    RestTemplate restTemplate = new RestTemplate();
    String response = null;
    String url = "https://someservice.com/getInfoOfIds?";
    restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor(userName, password));
    response = restTemplate.exchange(url+"ids=" + ids, HttpMethod.GET, null, String.class);
    return response;
}

Controller code:

@RequestMapping(value = "/getInfoOfIds", method = RequestMethod.GET)
public String getInfoOfIds(@RequestParam("ids") List<String> ids) {
    String response = myService.doSomeWork(ids);
    return response;
}

The call to he controller itself works but he List is not converting to the @RequestParam ids correctly.

How exactly do you pass a List from a RestTemplate to a Controller in Spring?

dsb
  • 121
  • 12
  • 1
    Possible duplicate of [Can Spring MVC handle multivalue query parameter?](https://stackoverflow.com/questions/9768509/can-spring-mvc-handle-multivalue-query-parameter) – Alan Hay Apr 27 '18 at 15:08

1 Answers1

5
response = restTemplate.exchange(url+"ids=" + ids, HttpMethod.GET, null, String.class);

In your client code it should be either comma separated values (ids=1,2,3) or multiple joined values (ids=1&ids=2&ids=3), but you're passing a whole object to restTemplate.exchange as a 1st argument which will be converted using toString() method and will look like this ids=[123, 321] and it differs from expected format.

Solution with formatted String

JDK >= 8

String idsAsParam = ids.stream()
            .map(Object::toString)
            .collect(Collectors.joining(","));

response = restTemplate.exchange(url+"ids=" + idsAsParam, HttpMethod.GET, null, String.class);

JDK < 8

String idsAsParam = ids.toString()
            .replace(", ", ",")  //remove space after the commas
            .replace("[", "")  //remove the left bracket
            .replace("]", "")  //remove the right bracket
            .trim();           //remove trailing spaces from partially initialized arrays

response = restTemplate.exchange(url + "ids=" + idsAsParam, HttpMethod.GET, null, String.class);

Solution with RestTemplate

You can also do the trick by using UriTemplate's pattern matching feature. It works well with Map object as an argument. The key should match URI key and the value should be an array, which can be created from list. Example:

String url = "http://google.com";

List<String> params = Arrays.asList("111", "222", "333");

Map<String, Object> map = new HashMap<>();
map.put("ids[]", params.toArray());

restTemplate.exchange(url + "?ids={ids[]}", HttpMethod.GET, null, String.class, map);

Results into

"http://google.com?ids=111,222,333"

Mikhail Kholodkov
  • 23,642
  • 17
  • 61
  • 78