我正在努力使自己了解Spring Boot和Reactors(已经离开Java近二十年了)。我正在从中学习的资源给出了过于基本的示例,并且没有搜索返回任何有意义的信息:只有复杂的文档无法解决任何问题。
我想要实现的目标-至少在原则上-非常简单。
我具有删除UPLOAD_ROOT
中存储的图像的功能。上载时,图像具有name
,并被分配了id
。然后将该图像存储为image.id + "-" + image.name
,(允许上传具有相同源文件名的多个图像)。 Image
类提供id
和name
值的关联,并将它们存储在MongoDB中。
通过Image
访问数据库public interface ImageRepository extends ReactiveCrudRepository <Image, String>
。
通过id
进行删除。此刻我的代码(源自一个按文件名删除的版本,并且没有处理名称冲突):
public Mono<Void> deleteImage(String fileId) {
return Mono.fromRunnable(() -> {
imageRepository.findById(fileId)
.map(image -> {
Mono<Void> deleteFile = Mono.fromRunnable(() -> {
try {
Files.deleteIfExists(Paths.get(UPLOAD_ROOT, image.getId() + "-" + image.getName()));
} catch (IOException e) {
throw new RuntimeException(e);
}
});
Mono<Void> deleteRecord = Mono.fromRunnable(() -> {
imageRepository.delete(image);
});
return Mono.when(deleteFile, deleteRecord).then();
});
}).then();
}
问题在于,包裹在imageRepository.findById(fileId).map(image -> { ... });
中的deleteFile和deleteRecord永远不会发生。也没有Mono.when()
。
对我来说更有意义的另一种方法是对.map
使用非转换性的替代函数,对提供的Mono<Image>
的元素进行操作并返回相同的{ {1}},以便可以做更多的事情。但是我找不到任何能使之实现的参考。
如何使所有嵌套函数真正发生? (我在Mono<Image>
和.then()
的最后都尝试了各种方法,但没有得到一致且完全有效的结果。)或者是否有一些秘密功能可以让我执行非转化链?
答案 0 :(得分:0)
使用Mono.fromRunnable
有点问题。
尝试以下代码:
public Mono<Void> deleteImage(String fileId) {
return imageRepository.findById(fileId)
.flatMap(image -> Mono.when(deleteFile(image), deleteRecord(image)).then());
}
private Mono<Void> deleteRecord(Image image) {
return imageRepository.delete(image);
}
private Mono<Void> deleteFile(Image image) {
return Mono.fromRunnable(() -> {
try {
Files.deleteIfExists(Paths.get(UPLOAD_ROOT, image.getId() + "-" + image.getName()));
} catch (IOException e) {
throw new RuntimeException(e);
}
})
}