我有一个反应式休息api(webflux),也使用
spring WebClient类,从其他休息服务请求数据.
简化设计:
@PostMapping(value = "/document")
public Mono save(@RequestBody Mono document){
//1st Problem: I do not know how to get the documentoOwner ID
//that is inside the Document class from the request body without using .block()
Mono documentOwner = documentOwnerWebClient()
.get().uri("/document-owner/{id}", document.getDocumentOwner().getId())
.accept(MediaType.APPLICATION_STREAM_JSON)
.exchange()
.flatMap(do -> do.bodyToMono(DocumentOwner.class));
//2nd Problem: I need to check (validate) if the documentOwner object is "active", for instance
//documentOwner and document instances below should be the object per se, not the Mono returned from the external API
if (!documentOwner.isActive) throw SomeBusinessException();
document.setDocumentOwner(documentOwner);
//Now I can save the document in some reactive repository,
//and return the one saved with the given ID.
return documentRepository.save(document)
}
换句话说:我理解(几乎)单独的所有反应性示例,但我无法将它们全部放在一起并构建一个简单的用例(get – > validate – > save – > return)而不会阻塞对象.
我越接近的是:
@PostMapping(value = "/document")
public Mono salvar(@RequestBody Mono documentRequest){
return documentRequest
.transform(this::getDocumentOwner)
.transform(this::validateDocumentOwner)
.and(documentRequest, this::setDocumentOwner)
.transform(this::saveDocument);
}
辅助方法有:
private Mono getDocumentOwner(Mono document) {
return document.flatMap(p -> documentOwnerConsumer.getDocumentOwner(p.getDocumentOwnerId()));
}
private Mono validateDocumentOwner(Mono documentOwner) {
return documentOwner.flatMap(do -> {
if (do.getActive()) {
return Mono.error(new BusinessException("Document Owner is Inactive"));
}
return Mono.just(do);
});
}
private DocumentOwnersetDocumentOwner(DocumentOwner documentOwner, Document document) {
document.setDocumentOwner(documentOwner);
return document;
}
private Mono saveDocument(Mono documentMono) {
return documentMono.flatMap(documentRepository::save);
}
我正在使用Netty,SpringBoot,Spring WebFlux和Reactive Mongo Repository.但是有一些问题:
1)我收到错误:
java.lang.IllegalStateException:只允许一个连接接收订阅者.也许是因为我使用相同的documentRequest转换和setDocumentOwner.我真的不知道.
2)没有调用setDocumentOwner方法.因此,不保存要保存的文档对象.我相信可以有更好的方法来实现这个setDocumentOwner().
谢谢