Spring Web 反应框架多部分文件问题
Spring Web Reactive Framework Multipart File Issue
我尝试通过以下尝试使用 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
我尝试了 headers 的不同变体和具有相同结果的文件。有点不知所措,因为我过去曾这样做过,而且一切似乎都还不错。我从这个post看到这个功能被合并了:
四处挖掘后,我在 Spring WebFlux 项目中找到了这个测试:
所以我缺少的部分是 @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));
}
}
实际上以下解决方案似乎适用于 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
故障排除步骤
通过检查方法确保 nio-multipart-parser 存在
org.springframework.http.codec.support.ServerDefaultCodecsImpl#extendTypedReaders
您可以通过在
中放置断点来检查是否使用了 nio-multipart-parser
org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader#canRead()
单个部分
org.springframework.http.codec.multipart.MultipartHttpMessageReader#canRead
用于多部分
以上方法之一应该return正确。
在某些情况下,解决方案是更新大于 2.1.1 的 Spring 版本,之后您应该检查不是 'spring-webmvc' 的依赖项,因为这会与 'spring-boot-starter-webflux'
我尝试通过以下尝试使用 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
我尝试了 headers 的不同变体和具有相同结果的文件。有点不知所措,因为我过去曾这样做过,而且一切似乎都还不错。我从这个post看到这个功能被合并了:
四处挖掘后,我在 Spring WebFlux 项目中找到了这个测试:
所以我缺少的部分是 @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));
}
}
实际上以下解决方案似乎适用于 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
故障排除步骤
通过检查方法确保 nio-multipart-parser 存在
org.springframework.http.codec.support.ServerDefaultCodecsImpl#extendTypedReaders
您可以通过在
中放置断点来检查是否使用了 nio-multipart-parserorg.springframework.http.codec.multipart.SynchronossPartHttpMessageReader#canRead()
单个部分org.springframework.http.codec.multipart.MultipartHttpMessageReader#canRead
用于多部分
以上方法之一应该return正确。
在某些情况下,解决方案是更新大于 2.1.1 的 Spring 版本,之后您应该检查不是 'spring-webmvc' 的依赖项,因为这会与 'spring-boot-starter-webflux'