我是反应编程(spring webflux)的新手,我想知道如何最好地处理这个用例。我有一个返回Mono的反应服务调用(getAccount),我想将它与另一个返回Mono
这里有一些假服务
public static Mono<String> getAccount(String name){
return Mono.just(name);
}
public static Mono<Set<Book> getBooks(String title){
return Mono.just(Sets.newHashSet(new Book(title + "One", "Author One"),
new Book(title +"Two", "Author Two"),
new Book(title + "Three", "Author Three")));
}
public static LibraryBook transform (Book a){
return new LibraryBook(a.getTitle(), a.getAuthorName(), "someUniqueId");
}
我想获得一个给定用户的帐户,找到他/她借阅的所有书籍,并转换这些书籍,以Mono
这是我的开始
public Mono<Set<LibraryBook>> getBorrowedBooks(String userId) {
return getAccount(userId)
.flatMap(account -> getBooks(account))
.log()
.map(books -> books.stream().map(book -> transform(book)).collect(Collectors.toSet()))
}
然而,我不确定混合反应和流是不是一件坏事,它只是看起来不对。
更新:
由于您不能修改getBooks方法,您可以按照以下方式构造getBorrowedBooks方法,以避免处理流。
注意-记录器和异常只是示例。您还可以以不同的方式处理空场景。
public class MyApp {
private static final Logger LOGGER = LoggerFactory.getLogger(MyApp.class);
public static void main(String[] args) {
List<LibraryBook> libraryBooks = getBorrowedBooks("Abhi").collectList().block();
libraryBooks.forEach(System.out::println);
}
public static Mono<String> getAccount(String name) {
return Mono.just(name);
}
public static Mono<Set<Book>> getBooks(String title) {
return Mono.just(Sets.newHashSet(new Book(title + "One", "Author One"),
new Book(title + "Two", "Author Two"),
new Book(title + "Three", "Author Three")));
}
public static LibraryBook transform(Book a) {
return new LibraryBook(a.getTitle(), a.getAuthorName(), "someUniqueId");
}
public static Flux<LibraryBook> getBorrowedBooks(String userId) {
return getAccount(userId)
.switchIfEmpty(Mono.defer(() -> {
LOGGER.error("No account found");
return Mono.error(new NoAccountFoundException());
}))
.flatMap(account -> getBooks(account))
.flatMapMany(Flux::fromIterable)
.switchIfEmpty(Mono.defer(() -> {
LOGGER.error("No books found for account");
return Mono.error(new NoBooksFoundForGivenAccountException());
}))
.map(MyApp::transform);
}
编译明智这是正确的。但从逻辑上来说,我认为这是不正确的,因为你没有考虑单声道和通量的定义。
单声道是由0..1个元素组成的流。通量是一种可以发射0..n个元素的流。
方法getBooks(顾名思义)应该为给定的标题发出1个以上的元素(这里是Book)。所以它的返回类型应该是flux而不是集合的Mono。
甚至可以从spring的反应存储库方法中获取示例:
现在,在reactive world中,移除重复项并将集合存储在hashset中的想法与对一系列元素调用distinct()同义。
因此您的getBooks方法应该如下所示:
public static Flux<Book> getBooks(String title){
return Flux.just(new Book(title + "One", "Author One"),
new Book(title +"Two", "Author Two"),
new Book(title + "Three", "Author Three"))
.distinct();
}
您的getBorrowedBooks方法应该如下所示:
public Flux<LibraryBook> getBorrowedBooks(String userId) {
return getAccount(userId)
.flatMapMany(account -> getBooks(account))
.log()
.map(book -> transform(book));
}
我不知道或问这个问题,除了这里,如果不是我道歉的地方。 这里有一个REST请求,它附带了一个简单的bean,其中包含一个列表等属性。对此列表进行迭代,以使用返回Mono(findOne)的响应mongo调用。但我不认为我找到了正确的方法: 在我看来,“反应性”的想法并不是必须做一个块,但我没有找到如何做,否则。 有人能帮我找到做这项任务的最佳方法吗?
我正在尝试使用SpringBoot2.0和新的reactive webFlux库。我想知道如何将通过无阻塞WebClient进行的两个调用的结果返回给我的Springboot API的调用者。我的代码是: 然而,如果我这样称呼它,我得到的回应是 而不是SearchResponse对象的内容。我觉得我可能错过了一个基本的点,这是如何工作的!我的想法是,因为WebClient没有阻塞,所以我可以向we
获取所有分支 遍历所有并将其添加到 返回,这是我不确定这样做是否正确的地方。但它起作用了 合并所有列表 我只是困惑,这是在我的上下文中使用的正确方式吗?或者有没有什么更好的方法来实现我正在努力做的事情?
我的代码如下 因为和都可能返回错误或空单声道。我想返回类似于消息取决于哪个Mono是空的。我该怎么做? 如果我在单声道之后添加一个。zip,我不知道哪个组件是空的。。。
我是Spring新来的。我在这里遇到了一个小问题“userMono不是空的”,但这部分代码正在执行“switchiffempty(Mono.just(“hello123”)”