Search code examples
springspring-mvcreactiveproject-reactor

Spring Web Reactive Framework Multipart File Issue


I'm trying to implement and image upload using Spring's Reactive Framework by trying the following:

@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(@RequestBody Mono<FilePart> part) throws Exception{
         return part.flatMap(file -> imageService.saveImage(file));
    }
}

But I keep getting a 415 with the following error message:

Response status 415 with reason "Content type 'multipart/form-data;boundary=--0b227e57d1a5ca41' not supported\

Not sure what the issue is, I'm curling the API the following way:

 curl -v -F "file=@jinyang.gif" -H "Content-Type: multipart/form-data" localhost:8080/images

I've tried different variations of headers and files with the same results. Kind of at a loss here because I've done this in the past and things seemed to work okay. I saw from this post that this feature was merged:

How to enable Spring Reactive Web MVC to handle Multipart-file?


Solution

  • 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));
        }
    }