Spring Web Reactive Framework Multipart File Issue
After digging around I was able to find this test in the Spring WebFlux project:
https://github.com/spring-projects/spring-framework/blob/master/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MultipartIntegrationTests.java
So the part I was missing was @RequestPart
instead of @RequestBody
in the controller definition.
Final code looks something like this:
@RestController
@RequestMapping("/images")
public class ImageController {
@Autowired
private IImageService imageService;
@PostMapping(value = "", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
Mono<ImageEntity> saveImage(@RequestPart("file") Mono<FilePart> part) throws Exception{
return part.flatMap(file -> imageService.saveImage(file));
}
}
Actually the following solution seems to work with Netty
@PostMapping(path = "/test/{path}",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
Mono<String> commandMultipart(
@PathVariable("path") String path,
@RequestPart("jsonDto") Mono<JsonDto> jsonDto,
@RequestPart(value = "file",required = false) Mono<FilePart> file) {
JsonDto dto = jsonDto.block();
}
Build.gradle
compile group: 'org.synchronoss.cloud', name: 'nio-multipart-parser', version: '1.1.0'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.3'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.3'
curl command in bash
echo '{"test":"1"}' > command.json && curl -H "Content-Type:multipart/form-data" -X POST http://localhost:8082/test/examplepath/ -F "command=@./command.json;type=application/json" -F "[email protected]" -vv
Troubleshooting steps
Ensure nio-multipart-parser is present by checking method
org.springframework.http.codec.support.ServerDefaultCodecsImpl#extendTypedReaders
You can check that nio-multipart-parser is used by placing breakpoint inside
org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader#canRead()
for single partorg.springframework.http.codec.multipart.MultipartHttpMessageReader#canRead
for multipart
One of the above methods should return true.