javaspringspring-mvcspring-boot

How to prevent Spring MVC from interpreting commas when converting to a Collection in Spring Boot?


We basically have the same problem as this question poses, but for lists and additionally, we are looking for a global solution.

Currently we have a REST call that is defined like this:

@RequestMapping
@ResponseBody
public Object listProducts(@RequestParam(value = "attributes", required = false) List<String> attributes) {

The call works fine and the list attributes will contain two elements "test1:12,3" and "test1:test2" when called like this:

product/list?attributes=test1:12,3&attributes=test1:test2

However, the list attributes will also contain two elements, "test1:12" and "3" when called as follows:

product/list?attributes=test1:12,3

The reason for this is, that in the first case, Spring will use a ArrayToCollectionConverter in the first case. In the second case it will use a StringToCollectionConverter which will split the argument using "," as a separator.

How can I configure Spring Boot to ignore the comma in the parameter? The solution should be global if possible.

What we have tried:

This question does not work for us, because we have a List instead of an array. Besides, this would be a controller-local solution only.

I also tried to add this configuration:

@Bean(name="conversionService")
public ConversionService getConversionService() {
    ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
    bean.setConverters(Collections.singleton(new CustomStringToCollectionConverter()));
    bean.afterPropertiesSet();
    return bean.getObject();
}

where CustomStringToCollectionConverter is a copy of the Spring StringToCollectionConverter, but without the splitting, however, the Spring converter still gets called preferentially.

On a hunch, I also tried "mvcConversionService" as a bean name, but that did not change anything either.


Solution

  • You can remove the StringToCollectionConverter and replace it with your own in WebMvcConfigurerAdapter.addFormatters(FormatterRegistry registry) method:

    Something like this:

    @Configuration
    public class MyWebMvcConfig extends WebMvcConfigurerAdapter {
      @Override
      public void addFormatters(FormatterRegistry registry) {
        registry.removeConvertible(String.class,Collection.class);
        registry.addConverter(String.class,Collection.class,myConverter);
      }
    }