Hi,
This issue has already been discussed in #399.
I got the same error with Feign 8.18.0, on a Swagger-codegen generated client (so i cannot modify the client). The annotations used are the good ones (feign.param for path params).
Interface :
@RequestLine("POST /client/session/{sessionUid}/slot/{slot}/sign")
@Headers({"Content-Type: application/json","Accept: application/json",})
SignResponse sign(@Param(value="sessionUid", expander=ParamExpander.class) String sessionUid, @Param(value="slot", expander=ParamExpander.class) Integer slot, SignRequest body);
Error:
java.lang.IllegalStateException: Body parameters cannot be used with form parameters.
However, if I change params order (body in first or second place) manually in the generated code, it works.
We ended up running into this issue because one of our path param had an underscore in it.
We made the path parameter camel case, and that resolved the issue.
Doesn't seem like you're running into that here, but maybe this will help someone in the future running into the same issue.
I had a "-" in the path parameter and was getting the same problem. The error resolved on making the parameter camelcase.
Sounds like something we should make clearer in the documentation.
I'm not really sure why a - would cause this. I'm going to flag this as a bug.
I've done some more research into this and this exception is thrown during contract parsing when we encounter a @Param annotated method parameter that does not have a corresponding variable in the @RequestLine template and an explicit request body parameter is also present.
Feign will treat method parameters annotated this way as application/www-form-urlencoded parameters, creating an implicit request body; therefore it is not possible to provide an explicit request body. Here is an example:
/*
* This will cause an exception. username and password will be treated as
* application/www-form-urlencoded request body parameters and Credentials
* are also being supplied as part of the request body. We cannot support both
*/
@RequestLine("POST /authenticate")
public User authenticate(
@Param("username") String username,
@Param("password") String password,
Credentials credentials);
Admittedly, the Contract checks this after each parameter processed. This means that if you change up the order of the parameters we will miss this check, causing undefined behavior. #1137 will fix the ordering issue.
In this particular case, there was a bug in RequestTemplate where the variable processing and identification was incorrect, due to our decision to encode variable names when registering them with the template. This explains why @JRJurman's change from _ to camel case corrected his issue. We corrected this in #778 and further refined this in #1138.
If anyone here is still experiencing this issue, can they test with version 10.7 and report if the issue is resolved?
Also #1144 has been merged and should correct any additional scenarios.
I am using 10.8 version , I am getting an exception saying "Body parameters cannot be used with form parameters." Below is my contract
ArrangementResponse createArrangement(
final @Param("Authorization") String authorization,
final @Param("CustomerToken") String customerToken,
final ArrangementRequest request
);
@ganeshabg on 10.9 feign adds more details to error message, would recommend using that version.
Most helpful comment
We ended up running into this issue because one of our path param had an underscore in it.
We made the path parameter camel case, and that resolved the issue.
Doesn't seem like you're running into that here, but maybe this will help someone in the future running into the same issue.