Reputation: 121
We have many @RestController receiving phrases in common language written by users. Phrases can be very long and contains punctuation, like periods and, of course, commas.
Simplified controller example:
@RequestMapping(value = "/countphrases", method = RequestMethod.PUT)
public String countPhrases(
@RequestParam(value = "phrase", required = false) String[] phrase) {
return "" + phrase.length;
}
Spring boot default behaviour is to split parameters values at comma, so the previous controller called with this url:
[...]/countphrases?phrase=john%20and%20me,%20you%and%her
Will return "2" istead of "1" like we want. In fact with the comma split the previous call is equivalent to:
[...]/countphrases?phrase=john%20and%20me&phrase=you%and%her
We work with natural language and we need to analyze phrases exactly how the users wrote them and to know exactly how many they wrote.
We tried this solution: https://stackoverflow.com/a/42134833/1085716 after adapting it to our spring boot version (2.0.5):
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
// we hoped this code could remove the "split strings at comma"
registry.removeConvertible(String.class, Collection.class);
}
}
But it doesn't work.
Anyone know how to globally remove the "spring boot split string parameters at comma" behaviour in spring boot 2.0.5?
Upvotes: 3
Views: 2073
Reputation: 2106
Replacing your formatter registry with a completely new list could make you loose some needed default formatters that would come with the framework. This will also disable all String-To-Collections parsing for the entire application, on every endpoint, such that if you want to a request filter such as the following at another endpoint, it won't work:
identifiers = 12,34,45,56,67
Solution: Just change your delimiter into something else... # or ; or $
identifiers = 12;23;34;45;56
This is what I have been doing, so I don't mess with all the goodies in the formatter registry.
Upvotes: 1
Reputation: 121
I find the solution. To override a default conversion we must add a new one. If we remove the old one only it doesn't work.
The correct (example) code should be:
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.removeConvertible(String.class, String[].class);
registry.addConverter(String.class, String[].class, noCommaSplitStringToArrayConverter());
}
@Bean
public Converter<String, String[]> noCommaSplitStringToArrayConverter() {
return new Converter<String, String[]>() {
@Override
public String[] convert(String source) {
String[] arrayWithOneElement = {source};
return arrayWithOneElement;
}
};
}
}
This way any controller like the one in the main question will not split parameters values:
Upvotes: 5