【问题标题】:Spring Web Reactive Framework Multipart File IssueSpring Web Reactive Framework 多部分文件问题
【发布时间】:2017-12-07 21:16:34
【问题描述】:

我正在尝试使用 Spring 的响应式框架来实现和图像上传,方法是尝试以下操作:

@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?

【问题讨论】:

  • 问题更多的是 Tomcat 与 Netty。对于上述工作,请使用 Netty。
  • 这是在 Netty 上的,底层服务器没有影响,见下文。

标签: spring spring-mvc reactive project-reactor


【解决方案1】:

四处挖掘后,我在 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));
    }
}

【讨论】:

    【解决方案2】:

    实际上下面的解决方案似乎适用于 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 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 "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 多部分

      上述方法之一应返回 true

    【讨论】:

      【解决方案3】:

      在某些情况下,解决方案是更新大于 2.1.1 的 Spring 版本,之后您应该检查不是“spring-webmvc”的依赖项,因为这会与“spring-boot-starter-”产生冲突webflux'

      【讨论】:

        猜你喜欢
        • 2019-09-14
        • 1970-01-01
        • 1970-01-01
        • 2011-10-10
        • 2021-05-29
        • 1970-01-01
        • 2015-04-02
        • 2022-06-17
        • 1970-01-01
        相关资源
        最近更新 更多