3

I'm trying to use the new reactive web-mvc implementation in a spring boot 2.0 application. I'm trying to define a method which consume multipart file but do not succeed at making it working :( - I always get a 415 error.

On one hand I have a controller containing the following request mapping :

@RequestMapping(method = RequestMethod.POST, path = "/myPath/{param}/{param2}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public Mono<Void> postFile(
        @RequestBody MultipartFile data,
        @PathVariable("param") String param,
        @PathVariable("param2") String param2,
        @RequestHeader(name = HEADER_DATE, required = false)   @DateTimeFormat(pattern = DATE_FORMAT) Instant instant
){
    return fileService.handleData(Mono.just(data), param, param2, instant);
}

On the other hand I had to add a server on the top of the basic dependencies as it seems netty do not handle multipart files. I so added the spring-boot-starter-tomcatdependency which enabled the MultipartAutoConfiguration to be matched and satisfied on application auto configuration.

When posting something using a curl call : curl 'Meta-Date: 20170101104532' --form "file=@file.bin" http://localhost:8082/myPath/foo/bar while debug logs are activated (logging.level.org.springframework.web=DEBUG) I got this exception : org.springframework.web.server.UnsupportedMediaTypeStatusException: Request failure [status: 415, reason: "Content type 'multipart/form-data;boundary=------------------------58fa43b8f1a26de4' not supported"]

This error is thrown by the RequestBodyArgumentResolver which has the the following supported media types : [*/*, text/xml, application/*+json;charset=UTF-8, application/xml, text/plain;charset=UTF-8, application/x-www-form-urlencoded, application/json;charset=UTF-8] provided by 9 DecoderHttpMessageReader.

Before posting I also took a look at :

My understanding is that Spring web 5.0 uses a new request decoder system as I don't find these classes on a spring 4 spring boot application, and there is not yet any DecoderHttpMessageReader dealing with multipart file Did I miss something ? Or should I wait one to be implemented ?

Community
  • 1
  • 1
Arthur Vaïsse
  • 1,551
  • 1
  • 13
  • 26

2 Answers2

3

Okay, It seems this is just not implemented for now as it currently exists a pull request for this feature : Add reactive multipart request support #1201

Should have check this earlier...

[EDIT] : The issue has been solved and merged into Spring master branch. Should no longer be an issue.

Arthur Vaïsse
  • 1,551
  • 1
  • 13
  • 26
  • 3
    I think it is available in the latest Spring 5, I have written a small demo for multipart, check here: https://github.com/hantsy/spring-reactive-sample/tree/master/multipart , do not forget to add artifact `nio-multipart-parser` into your project dependencies explicitly, at the moment, Spring Boot 2.0.0.M3 does not include it in the webflux-starter. – Hantsy Sep 10 '17 at 12:02
  • I'll check it this week. If correct I'll update the answer to indicate it clearly. – Arthur Vaïsse Sep 11 '17 at 20:02
1
@PutMapping(value="/{..}",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<Void> save(@RequestPart("file") FilePart multipartFormData,@RequestParam("fileName") String fileName,@PathVariable("..") String ..) throws IOException {        
        List<ByteBuffer> bytesList = new LinkedList<>();

        multipartFormData.content().
          subscribe(item->bytesList.add(item.asByteBuffer()));

        int totalBytes = bytesList.stream().mapToInt(item->item.capacity()).sum();

        ByteBuffer buffer =  ByteBuffer.allocate(totalBytes);
        bytesList.stream().forEach(byteBuff->buffer.put(byteBuff));
        baseImageHandler.saveImage(buffer, fileName, baseItemId);
        return Mono.empty();
    }

Please note that it is a dev verison, but this is how I have managed to do it.

Alex
  • 389
  • 1
  • 2
  • 14