Hi,
Below is my technology stack: Spring Boot --> 2.1.6.RELEASE spring-cloud-starter-openfeign --> 2.1.2.RELEASE feign-form-spring --> 3.3.0
I have following code in my Interface of Rest Controller Implementation
@PostMapping(value = "/files", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
ResponseEntity<Output> createFile(
@RequestPart("file") MultipartFile file,
@RequestPart("properties") Map<String, String> properties);
My Feign client just extends this interface and it has Feign Client Annotation like below
@FeignClient(name = "feign-client", url = "${host}/store/v1/", configuration = FeignConfig.class)
public interface StoreClient extends StoreInterface {
}
When I try to start my Spring Boot app, I get below exception
Caused by: java.lang.IllegalStateException: Method has too many Body parameters: public abstract org.springframework.http.ResponseEntity au.com.macquarie.bfs.ml.store.v1.StoreClient.createFile(org.springframework.web.multipart.MultipartFile,java.util.Map)
I tried googling and adopting many solutions, but looks like this is not supported yet.
Can some one help me resolve this and get around?
Comment From: ryanjbaxter
If you place the createFile method in the the Feign interface itself does it work?
Comment From: mazkozi
Nope. It doesnt.
Comment From: bpzhang
try to add a config file like this:
@Configuration
public class MultipartSupportConfig {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Encoder feignFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
Comment From: mazkozi
Hi @bpzhang . I did try this and it didn't work either.
Comment From: poznachowski
SpringMvcContract seems to process @RequestParam annotations, not @RequestPart ones.
Comment From: ryanjbaxter
This should work as it was addressed in https://github.com/spring-cloud/spring-cloud-openfeign/issues/62.
What version are you using?
Comment From: j-bernard
The problem here is not to support MultipartFile but to support 2 @RequestPart. @mazkozi did you find a workaround?
Comment From: mazkozi
The problem here is not to support
MultipartFilebut to support 2@RequestPart. @mazkozi did you find a workaround?
Hi j-bernand, I had to remove one @RequestPart. That is the only way I could get it work.
Comment From: thekalinga
I tried this on spring-cloud-openfeign-core-2.1.1.RELEASE & I see this to be a problem
Unless I remove one of the request part, the proxy creation fails
With this bug in place, I cant send a multipart request with multiple parts
Comment From: thekalinga
This is what I have
@PostMapping(value = "/fileUpload", produces = MULTIPART_FORM_DATA_VALUE)
String multipartRequest(@RequestPart("file") MultipartFile file, @RequestPart("additionalFormArg") String additionalFormArg);
Comment From: MrBogue
+1
Comment From: antemooo
@thekalinga @MrBogue
If you are still facing the problem, look to the Issue #62 . After reading the issue which provide a solution, I put another solution in the comments. You can directly see it here
Comment From: arbarre
I'm facing the same issue mentioned by @thekalinga and @mazkozi and would love to see a solution to this...
@thekalinga @MrBogue
If you are still facing the problem, look to the Issue #62 . After reading the issue which provide a solution, I put another solution in the comments. You can directly see it here
Actually I don't see how it solves the issue exposed here (correct me if I'm wrong, but it doesn't seem you are dealing with multiple @RequestPart).
Comment From: tchibatron
Looks like this feature is not supported yet...
Comment From: aaronjwhiteside
+1 here too, the multipart support of MultipartFile isn't working.
Ideally the following should also be supported:
@PostMapping(value = "/fileUpload", consumes = MULTIPART_FORM_DATA_VALUE)
String multipartRequest(@RequestPart("file1") MultipartFile file1, @RequestPart("file2") MultipartFile file2);
@PostMapping(value = "/fileUpload", consumes = MULTIPART_FORM_DATA_VALUE)
String multipartRequest(@RequestPart("files") List<MultipartFile> files);
@PostMapping(value = "/fileUpload", consumes = MULTIPART_FORM_DATA_VALUE)
String multipartRequest(@RequestPart("something") String something, @RequestPart("dto") SomeDto someDto, @RequestPart("files") List<MultipartFile> files);
Also from the @RequestPart javadoc, it should be possible to mix and match @RequestParam in a multipart/form-data request too..
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestPart.html
Note that @RequestParam annotation can also be used to associate the part of a "multipart/form-data" request with a method argument supporting the same method argument types. The main difference is that when the method argument is not a String or raw MultipartFile / Part, @RequestParam relies on type conversion via a registered Converter or PropertyEditor while RequestPart relies on HttpMessageConverters taking into consideration the 'Content-Type' header of the request part. RequestParam is likely to be used with name-value form fields while RequestPart is likely to be used with parts containing more complex content e.g. JSON, XML).
So the following should be supported too:
@PostMapping(value = "/fileUpload", consumes = MULTIPART_FORM_DATA_VALUE)
String multipartRequest(@RequestParam("something") SomeDto someDto, @RequestPart("file") MultipartFile file);
@PostMapping(value = "/fileUpload", consumes = MULTIPART_FORM_DATA_VALUE)
String multipartRequest(@RequestParam("something") String something, @RequestPart("file") MultipartFile file);
However this raises the question of how do you know if something should be a query parameter vs a form parameter.. perhaps it's best to ignore this at the moment and put everything with a @RequestPart annotation in multipart body..
Comment From: aaronjwhiteside
I have a fix for this in the works, just writing comprehensive tests at the moment, expect a pull request soon.
Comment From: josoriorios
I'm having the same issue in my project, I couldn't find a fix for it so, I had to change one of the two parameters to "@RequestParam" annotation. I hope the library could support it soon.
Comment From: wakedeer
works! If feign doesn't sent POJO - just add bean JsonFormWriter in feign configuration:
import org.springframework.cloud.openfeign.support.AbstractFormWriter;
import org.springframework.cloud.openfeign.support.JsonFormWriter;
@Configuration
@ComponentScan
@EnableFeignClients
public class ClientConfiguration {
@Bean
public AbstractFormWriter jsonFormWriter() {
return new JsonFormWriter();
}
}
Thanks @darrenfoong for the fix: https://github.com/spring-cloud/spring-cloud-openfeign/pull/314
Comment From: voduku
@wakedeer can you help me with this issue? I am current using spring boot 2.4.1 and cloud 2020.0.0 but this api give me a
feign.codec.EncodeException: Error converting request body
@PostMapping("/storage/files")
ResponseWrapper<FileDTO> uploadFile(@RequestPart("file") MultipartFile file, @RequestPart("folderPath") String folderPath,
@RequestPart("isPublic") String isPublic);
Comment From: wakedeer
@wakedeer can you help me with this issue? I am current using spring boot 2.4.1 and cloud 2020.0.0 but this api give me a
feign.codec.EncodeException: Error converting request body@PostMapping("/storage/files") ResponseWrapper<FileDTO> uploadFile(@RequestPart("file") MultipartFile file, @RequestPart("folderPath") String folderPath, @RequestPart("isPublic") String isPublic);
Hey @VuDo98, unfortunately I haven't run into the same issue. I suppose, you'd better use stackoverflow for such questions. Can you add an example or more details ? Thanks
Comment From: Xu-Justin
If you have this issue and have tried all solutions above but still couldn't solve it, try this:
@PostMapping(value = "/files", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
ResponseEntity<Output> createFile(
@PathVariable("file") MultipartFile file,
@PathVariable("properties") Map<String, String> properties);
This solution solved mine.