Hello. I saw a lot of similar issues, but looks like the problem is not resolved. I'm using Spring Boot 2.7.3 and Spring Cloud 2021.0.4 and getting startup error Method has too many Body parameters. In my project I have an external library (I can't modify it) that declares REST API interface using Spring Web annotations:
@PostMapping("/list")
Page<String> listElements(Pageable pageable, @RequestBody(required = false) String body);
When I try to create Feign client for it I'm getting error that I mentioned earlier. I start debugging the code and figured out that it does not matter either PageableSpringEncoder or PageableSpringQueryMapEncoder are registered or not - the code will fail earlier, even before those encoders take in place. So, the problem is that Pageable does not handled anyhow in "initialization" phase and is counted as a body and then, when method parser shifts to next method argument, it finds real "body" argument and fails, thinking that there are 2 bodies.
Want to pay attention, that this guide does not help. Furthermore, looks like this will not work for Spring MVC, because actually Spring awaits multiple sort query parameters for multi-sort request, instead of single comma-separated parameter.
I was managed to find workaround for that by creating next class and registering it instead of original SpringMvcContract:
public class SpringMvcContractFixed extends SpringMvcContract {
public SpringMvcContractFixed(List<AnnotatedParameterProcessor> annotatedParameterProcessors, ConversionService conversionService, boolean decodeSlash) {
super(annotatedParameterProcessors, conversionService, decodeSlash);
}
@Override
protected boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex) {
if (data.method().getParameterTypes()[paramIndex].isAssignableFrom(Pageable.class)) {
data.queryMapIndex(paramIndex);
return false;
}
return super.processAnnotationsOnParameter(data, annotations, paramIndex);
}
}
But this does not looks good for me, because this solution tricks Feign and make him think that Pageable is a SpringQueryMap.
Any ideas how to resolve the problem in nice way?
Here is example project to reproduce this problem, just run DemoApplicationTests JUnit test.
Comment From: valkuc
Small update regarding CollectionFormat - using it will generate next request:
http://localhost:8080/list?size=1&page=0&sort=name,ASC,publishDate,ASC
And the request will fail with error No property 'ASC' found for type 'MyObjectClass'.
The valid request is
http://localhost:8087/list?size=1&page=0&sort=name,ASC&sort=publishDate,ASC
and is generated by default without using CollectionFormat.
Comment From: valkuc
Any updates?
Comment From: OlgaMaciaszek
Hello @valkuc. Thanks for reporting it. We'll take a look at it.
Comment From: OlgaMaciaszek
@valkuc when it comes to the main issue that you're describing, I was able to reproduce it. I think your workaround is a good solution. By setting it we're indicating for it to be processed as a queryMap while constructing the request, which is the way it should be done for a correct request. Let me know if you would like to submit a PR with the fix or if you'd prefer us to take care of it.
When it comes to the second issue (with @CollectionFormat suggestion in the docs), I've tried it on your sample and haven't seen any issues - got a properly generated request that was processed by a server expecting Pageable param. If you want me to take another look, please update your demo so that it'll be reproduced.
Comment From: valkuc
Hello Olga. Thanks for checking this issue.
Regarding first part - yep, feel free to take care of it.
Regarding second. So, you want to say that request was http://localhost:8087/list?size=1&page=0&sort=name,ASC&sort=publishDate,ASC (pay attention on multiple sort query params)? If yes, then maybe issue has been already resolved indirectly.
Comment From: OlgaMaciaszek
Haven't tried with multiple params. Will check it.
Comment From: OlgaMaciaszek
@valkuc with multiple parameters I do get an additional, incorrect sort parameter. That used to work fine before, but must have been affected by changes in dependencies. Will remove this snippet from the docs as well.