7

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.

Community
  • 1
  • 1
ircecho
  • 93
  • 1
  • 8
  • Some solutions are here https://stackoverflow.com/questions/4998748/how-to-prevent-parameter-binding-from-interpreting-commas-in-spring-3-0-5 – xtian Feb 24 '22 at 21:29

3 Answers3

8

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);
  }
}
Strelok
  • 50,229
  • 9
  • 102
  • 115
2

For me it worked fine even without the line for adding a new converter but because @Strelok did not provide an example how to write a new converter here is a full solution:

@Configuration
class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.removeConvertible(String.class, Collection.class);
        registry.addConverter(String.class, Collection.class, noCommaSplitStringToCollectionConverter());
    }

    public Converter<String, Collection> noCommaSplitStringToCollectionConverter() {
        return Collections::singletonList;
    }

}

My version is a modified and update one of a string to array converter you can find here: How to disable spring boot parameter split

Neonchen
  • 141
  • 1
  • 6
0

I managed to solve the problem by applying the following: how-to-prevent-parameter-binding-from-interpreting-commas-in-spring-3-0-5

The trick is done by the following lines of code

@InitBinder
public void initBinder(WebDataBinder binder) {
  binder.registerCustomEditor(String[].class, new StringArrayPropertyEditor(null));
}

More information: Why escaped comma is the delimiter for @RequestParam List?