17

By default Spring MVC assumes @RequestParam to be required. Consider this method (in Kotlin):

fun myMethod(@RequestParam list: List<String>) { ... }

When passing empty list from javaScript, we would call something like:

$.post("myMethod", {list: []}, ...)

In this case however, as the list is empty, there is no way to serialize empty list, so the parameter essentially disappears and so the condition on required parameter is not satisfied. One is forced to use the required: false on the @RequestParam annotation. That is not nice, because we will never receive the empty list, but null.

Is there a way to force Spring MVC always assume empty lists in such case instead of being null?

Vojtěch
  • 11,312
  • 31
  • 103
  • 173

4 Answers4

41

To get Spring to give you an empty list instead of null, you set the default value to be an empty string:

@RequestParam(required = false, defaultValue = "")
Laplie Anderson
  • 6,345
  • 4
  • 33
  • 37
3

This can be managed in the serialization with ObjectMapper. If you are using jackson in your spring MVC, you can do either the following.

1) Configure your object mapper:

objectMapper.configure(SerializationConfig.Feature.WRITE_EMPTY_JSON_ARRAYS, false);

2) Or if you are using beans via xml config:

<bean name="objectMapper" class="org.springframework.http.converter.json.JacksonObjectMapperFactoryBean" autowire="no">
    <property name="featuresToDisable">
        <list>
            <value type="org.codehaus.jackson.map.SerializationConfig.Feature">WRITE_EMPTY_JSON_ARRAYS</value>
        </list>
    </property>
</bean>
Adam Michalik
  • 9,678
  • 13
  • 71
  • 102
Winnnn
  • 56
  • 4
1

You can try a WebDataBinder in your controller.

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(List.class, "list", new CustomCollectionEditor( List.class, true));
}
Johna
  • 1,836
  • 2
  • 18
  • 29
  • I am looking for a general solution, meaning not within a single controller. – Vojtěch Aug 08 '18 at 07:37
  • Instead of putting this `@InitBinder` method in a controller, you can put it inside a class annotated with `@ControllerAdvise`. Then it will apply to all the controllers. – Johna Aug 09 '18 at 23:20
  • The CustomCollectionEditor 's second argument is exactly what I'm looking for. Setting the "default" to empty string doesn't make the list empty but a one-empty-element list instead. – emeraldhieu Dec 04 '22 at 15:35
0

Tried this?

fun myMethod(@RequestParam list: List<String> = listOf()) { ... }