Spring Web Reactive Framework多部分文件问题

时间:2017-12-07 21:16:35

标签: spring spring-mvc reactive project-reactor

尝试使用Spring的Reactive Framework尝试实现和图像上传,尝试以下方法:

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

但是我一直收到415,并出现以下错误消息:

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

不确定问题是什么,我通过以下方式卷曲API:

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

我尝试过不同的标题和文件变体,结果相同。这里有点不知所措,因为我过去做过这件事情似乎工作正常。我从这篇文章中看到这个功能已合并:

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

3 个答案:

答案 0 :(得分:4)

在挖掘之后,我能够在Spring WebFlux项目中找到这个测试:

https://github.com/spring-projects/spring-framework/blob/master/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MultipartIntegrationTests.java

因此,我缺少的部分是@RequestPart,而不是控制器定义中的@RequestBody

最终代码如下所示:

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

答案 1 :(得分:0)

实际上,以下解决方案似乎适用于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'
bash中的

curl 命令

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 "file=@test.bin" -vv

疑难解答步骤

  1. 通过检查方法确保存在nio-multipart-parser org.springframework.http.codec.support.ServerDefaultCodecsImpl#extendTypedReaders

  2. 您可以通过在

    中放置断点来检查是否使用了nio-multipart-parser
      单个部分
    • org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader#canRead()
    • org.springframework.http.codec.multipart.MultipartHttpMessageReader#canRead for multipart

    上述方法之一应返回 true

答案 2 :(得分:0)

在某些情况下,解决方案是更新大于2.1.1的Spring版本,此后您应检查非'spring-webmvc'的依赖项,因为这会与'spring-boot-starter- webflux'