我有一个被动rest api(webflux),也使用spring WebClient
类来请求来自其他休息服务的数据。Spring Reactive WebClient
简化设计:
@PostMapping(value = "/document")
public Mono<Document> save(@RequestBody Mono<Document> 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> 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)
}
换句话说:我明白了(几乎)所有的单独的反应的例子,但我不能把它一起,构建一个简单的用例(获得 - >验证 - >保存 - >返回),而不会阻塞对象。
越接近我能得到的是:
@PostMapping(value = "/document")
public Mono<Document> salvar(@RequestBody Mono<Document> documentRequest){
return documentRequest
.transform(this::getDocumentOwner)
.transform(this::validateDocumentOwner)
.and(documentRequest, this::setDocumentOwner)
.transform(this::saveDocument);
}
附配的方法是:
private Mono<DocumentOwner> getDocumentOwner(Mono<Document> document) {
return document.flatMap(p -> documentOwnerConsumer.getDocumentOwner(p.getDocumentOwnerId()));
}
private Mono<DocumentOwner> validateDocumentOwner(Mono<DocumentOwner> 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<Document> saveDocument(Mono<Document> documentMono) {
return documentMono.flatMap(documentRepository::save);
}
我使用了Netty,SpringBoot,春WebFlux和无功蒙戈库。但有一些问题:
1)我收到错误: java.lang.IllegalStateException:只有一个连接接收订阅者允许。也许是因为我正在使用相同的documentRequest来转换和setDocumentOwner。我真的不知道。
2)setDocumentOwner方法没有被调用。所以要保存的文档对象不会更新。我相信可以有更好的方法来实现这个setDocumentOwner()。
谢谢
随着错误消息解释,获取的响应时,你不能指望一个'Mono'返回类型与服务器发送事件的内容类型。如果你期待一个单一的JSON对象,那么''application/json''会更适合。请先解决此问题,然后更新您的问题。 –
@BrianClozel,完美!我编辑了我的问题。 –
已编辑的问题。 –