Fel*_*era 2 java spring spring-webflux
我正在使用 Spring WebFlux 开发 API REST,但在上传文件时遇到问题。它们被存储,但我没有得到预期的返回值。
这就是我所做的:
我希望返回文件名,但客户端得到一个空字符串。
控制器代码
@PostMapping(value = "/muscles/{id}/image")
public Flux<String> updateImage(@PathVariable("id") String id, @RequestBody Flux<Part> file) {
log.info("REST request to update image to Muscle");
return storageService.saveFiles(file);
}
Run Code Online (Sandbox Code Playgroud)
存储服务
public Flux<String> saveFiles(Flux<Part> parts) {
log.info("StorageService.saveFiles({})", parts);
return
parts
.filter(p -> p instanceof FilePart)
.cast(FilePart.class)
.flatMap(file -> saveFile(file));
}
private Mono<String> saveFile(FilePart filePart) {
log.info("StorageService.saveFile({})", filePart);
String filename = DigestUtils.sha256Hex(filePart.filename() + new Date());
Path target = rootLocation.resolve(filename);
try {
Files.deleteIfExists(target);
File file = Files.createFile(target).toFile();
return filePart.transferTo(file)
.map(r -> filename);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Run Code Online (Sandbox Code Playgroud)
FilePart.transferTo()return Mono<Void>,它在操作完成时发出信号 - 这意味着反应式Publisher只会发布一个onComplete/onError信号并且在此之前永远不会发布值。
这意味着该map操作从未执行过,因为它只给定了源发布的元素。
您可以返回文件的名称并仍然链接反应式运算符,如下所示:
return part.transferTo(file).thenReturn(part.filename());
Run Code Online (Sandbox Code Playgroud)
从Reactor 3.2 开始,禁止block在反应式管道中使用运算符,它甚至在运行时抛出异常。
使用subscribe作为替代也不好,因为subscribe会脱钩从请求处理的传输过程,使得在不同的执行顺序的发生。这意味着您的服务器可以完成处理请求并关闭 HTTP 连接,而另一部分仍在尝试读取文件部分以将其复制到磁盘上。这很可能在运行时以微妙的方式失败。
| 归档时间: |
|
| 查看次数: |
2289 次 |
| 最近记录: |