[java] Binding a list in @RequestParam

I'm sending some parameters from a form in this way:

myparam[0]     : 'myValue1'
myparam[1]     : 'myValue2'
myparam[2]     : 'myValue3'
otherParam     : 'otherValue'
anotherParam   : 'anotherValue' 
...

I know I can get all the params in the controller method by adding a parameter like

public String controllerMethod(@RequestParam Map<String, String> params){
    ....
}

I want to bind the parameters myParam[] (not the other ones) to a list or array (anything that keeps the index order), so I've tried with a syntax like:

public String controllerMethod(@RequestParam(value="myParam") List<String> myParams){
    ....
}

and

public String controllerMethod(@RequestParam(value="myParam") String[] myParams){
    ....
}

but none of them are binding the myParams. Even when I add a value to the map it is not able to bind the params:

public String controllerMethod(@RequestParam(value="myParam") Map<String, String> params){
    ....
}

Is there any syntax to bind some params to a list or array without having to create an object as @ModelAttribute with a list attribute in it?

Thanks

This question is related to java spring data-binding collections spring-mvc

The answer is


Change hidden field value with checkbox toggle like below...

HTML:

<input type='hidden' value='Unchecked' id="deleteAll" name='anyName'>
<input type="checkbox"  onclick="toggle(this)"/> Delete All

Script:

function toggle(obj) {`var $input = $(obj);
    if ($input.prop('checked')) {

    $('#deleteAll').attr( 'value','Checked');

    } else {

    $('#deleteAll').attr( 'value','Unchecked');

    }

}

It wasn't obvious to me that although you can accept a Collection as a request param, but on the consumer side you still have to pass in the collection items as comma separated values.

For example if the server side api looks like this:

@PostMapping("/post-topics")
public void handleSubscriptions(@RequestParam("topics") Collection<String> topicStrings) {

    topicStrings.forEach(topic -> System.out.println(topic));
}

Directly passing in a collection to the RestTemplate as a RequestParam like below will result in data corruption

public void subscribeToTopics() {

    List<String> topics = Arrays.asList("first-topic", "second-topic", "third-topic");

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.postForEntity(
            "http://localhost:8088/post-topics?topics={topics}",
            null,
            ResponseEntity.class,
            topics);
}

Instead you can use

public void subscribeToTopics() {

    List<String> topicStrings = Arrays.asList("first-topic", "second-topic", "third-topic");
    String topics = String.join(",",topicStrings);

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.postForEntity(
            "http://localhost:8088/post-topics?topics={topics}",
            null,
            ResponseEntity.class,
            topics);
}

The complete example can be found here, hope it saves someone the headache :)


Or you could just do it that way:

public String controllerMethod(@RequestParam(value="myParam[]") String[] myParams){
    ....
}

That works for example for forms like this:

<input type="checkbox" name="myParam[]" value="myVal1" />
<input type="checkbox" name="myParam[]" value="myVal2" />

This is the simplest solution :)


One way you could accomplish this (in a hackish way) is to create a wrapper class for the List. Like this:

class ListWrapper {
     List<String> myList; 
     // getters and setters
}

Then your controller method signature would look like this:

public String controllerMethod(ListWrapper wrapper) {
    ....
}

No need to use the @RequestParam or @ModelAttribute annotation if the collection name you pass in the request matches the collection field name of the wrapper class, in my example your request parameters should look like this:

myList[0]     : 'myValue1'
myList[1]     : 'myValue2'
myList[2]     : 'myValue3'
otherParam    : 'otherValue'
anotherParam  : 'anotherValue'

Just complementing what Donal Fellows said, you can use List with @RequestParam

public String controllerMethod(@RequestParam(value="myParam") List<ObjectToParse> myParam){
....
}

Hope it helps!


Subscribing what basil said in a comment to the question itself, if method = RequestMethod.GET you can use @RequestParam List<String> groupVal.

Then calling the service with the list of params is as simple as:

API_URL?groupVal=kkk,ccc,mmm

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to spring

Are all Spring Framework Java Configuration injection examples buggy? Two Page Login with Spring Security 3.2.x Access blocked by CORS policy: Response to preflight request doesn't pass access control check Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified Spring Data JPA findOne() change to Optional how to use this? After Spring Boot 2.0 migration: jdbcUrl is required with driverClassName The type WebMvcConfigurerAdapter is deprecated No converter found capable of converting from type to type

Examples related to data-binding

Angular 2 Checkbox Two Way Data Binding Get user input from textarea Launch an event when checking a checkbox in Angular2 Angular 2 two way binding using ngModel is not working Binding ComboBox SelectedItem using MVVM Implement Validation for WPF TextBoxes Use StringFormat to add a string to a WPF XAML binding how to bind datatable to datagridview in c# How to format number of decimal places in wpf using style/template? AngularJS - Binding radio buttons to models with boolean values

Examples related to collections

Kotlin's List missing "add", "remove", Map missing "put", etc? How to unset (remove) a collection element after fetching it? How can I get a List from some class properties with Java 8 Stream? Java 8 stream map to list of keys sorted by values How to convert String into Hashmap in java How can I turn a List of Lists into a List in Java 8? MongoDB Show all contents from all collections Get nth character of a string in Swift programming language Java 8 Distinct by property Is there a typescript List<> and/or Map<> class/library?

Examples related to spring-mvc

Two Page Login with Spring Security 3.2.x ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean Spring 5.0.3 RequestRejectedException: The request was rejected because the URL was not normalized The type WebMvcConfigurerAdapter is deprecated RestClientException: Could not extract response. no suitable HttpMessageConverter found Spring boot: Unable to start embedded Tomcat servlet container UnsatisfiedDependencyException: Error creating bean with name 8080 port already taken issue when trying to redeploy project from Spring Tool Suite IDE Error creating bean with name 'entityManagerFactory' defined in class path resource : Invocation of init method failed Difference between the annotations @GetMapping and @RequestMapping(method = RequestMethod.GET)