54

Having this http://myserver/find-by-phones?phone=123&phone=345 request, is it possible to handle with something like this:

@Controller
public class Controller{
    @RequestMapping("/find-by-phones")
    public String find(List<String> phones){
       ...
    }
}

Can Spring MVC some how convert multi-value param phones to a list of Strings (or other objects?

Thanks.

Alex

AlexV
  • 3,836
  • 7
  • 31
  • 37
  • 2
    `find(@RequestParam(required=false, value="phone") List phones)` should work. This works for `url?phone=123&phone=345` and also for `url?phone=123,345` and for `null` parameter value like `url` or `url?phone=` I hope this helps anyone looking for this solution :) – Diablo Mar 16 '16 at 14:45
  • 1
    If you have multiple parameters all of which can have multiple values, use a MultiValueMap. See https://stackoverflow.com/questions/22398892/how-to-capture-multiple-parameters-using-requestparam-using-spring-mvc – chrisinmtown Jan 16 '18 at 19:58

3 Answers3

92

"Arrays" in @RequestParam are used for binding several parameters of the same name:

phone=val1&phone=val2&phone=val3

-

public String method(@RequestParam(value="phone") String[] phoneArray){
    ....
}

You can then convert it into a list using Arrays.asList(..) method

EDIT1:

As suggested by emdadul, latest version of spring can do like below as well:

public String method(@RequestParam(value="phone", required=false) List<String> phones){
    ....
}
fmucar
  • 14,361
  • 2
  • 45
  • 50
  • 1
    if there is not a single param out there, will phoneArray be null or be an empty array ? – Bertie Mar 13 '13 at 11:17
  • 28
    Spring can put the values directly into a list: `@RequestParam(value="phone") List phones`. Not sure if/when this was changed, but it works in Spring 3.0.5. – jtoberon Nov 20 '13 at 15:17
  • 1
    @Nailgun can you set some sort of proper default parameter and generate an empty Array or do just have to handle the null? Thank you – Andrew Cassidy Nov 11 '14 at 20:00
  • 2
    what about form element name will it be phone[ ] or phone or phone[0],phone[1] ..... ? I have 25 mcq questions with 4 radio button for each question. – Govinda Sakhare Apr 15 '15 at 11:56
  • Element name is going to be phone – fmucar Apr 15 '15 at 13:47
  • `@RequestParam(value="phone", required=false) List phones)` will work, `required=false` is for missing parameter cases. otherwise spring throws parameter missing error – Diablo Mar 16 '16 at 14:51
  • @piechuckerr not sure about using an index like `phone[1]`, but if your 'query array' syntax looks like this: `phone[]=123&phone[]=456&phone[]=789` then the following should work: `@RequestParam(value="phone[]") List phones` – mlehmeher Dec 15 '17 at 01:19
  • @fmucar Please update your answer, as we can use List phones now. – Emdadul Sawon Oct 24 '18 at 07:22
  • Note that if you ever want to pass in a single element that contains a comma, you're in trouble, since Spring will treat the comma as a list delimiter. e.g. `?phone=A,B` would result in `{"A", "B"}`, not `{"A,B"}`. It does work if there are more than one element, though, e.g. `?phone=A,B&phone=C`, which gives `{"A,B", "C"}`. – M. Justin May 15 '20 at 22:18
11

Spring can convert the query param directly into a List or even a Set

for example:

 @RequestParam(value = "phone", required = false) List<String> phones

or

 @RequestParam(value = "phone", required = false) Set<String> phones
Marquis Blount
  • 7,585
  • 8
  • 43
  • 67
4

I had an issue with indexed querystring like

http://myserver/find-by-phones?phone[0]=123&phone[1]=345
and only handling with
MultiValueMap<String, String>
worked for me. Neither List or String[] were handling it properly.

I also tried

@RequestParam("phones[]")
but RequestParamMethodArgumentResolver is looking explicitly for phones[] ignoring indexes. So that is why I decided to let RequestParamMapMethodArgumentResolver handle it.
mlecar
  • 729
  • 6
  • 9