Java 如何在Mono中操作列表属性作为通量?
我是project reactor的新手,我正在尝试将Java 如何在Mono中操作列表属性作为通量?,java,spring-boot,reactive-programming,project-reactor,Java,Spring Boot,Reactive Programming,Project Reactor,我是project reactor的新手,我正在尝试将列表中的一些字段操作为Mono中的Flux 因此,我有一个名为lines的属性Mono,它是一个列表。 然后,对于每一条线路,我都必须呼叫两个外部服务来获取一些额外的信息 这是我的密码: Mono<Basket> basketMono = //this doesn't work cause I map it to a Flux Mono.just(basket) .flatMapItera
列表中的一些字段操作为Mono中的Flux
因此,我有一个名为lines
的属性Mono
,它是一个列表
。
然后,对于每一条线路,我都必须呼叫两个外部服务来获取一些额外的信息
这是我的密码:
Mono<Basket> basketMono = //this doesn't work cause I map it to a Flux
Mono.just(basket)
.flatMapIterable(Basket::getLines)
.parallel(...)
.runOn(...)
.map((line) -> {
line.setInfo1(externalService1.getInfo());
line.setInfo2(externalService2.getInfo());
return line;
});
Mono basketMono=//这不起作用,因为我将它映射到一个通量
单声道(篮球)
.flatMapIterable(Basket::getLines)
.平行(…)
.runOn(…)
.map((行)->{
line.setInfo1(externalService1.getInfo());
line.setInfo2(externalService2.getInfo());
回流线;
});
我这里的主要问题是,我不知道如何将这些附加信息设置为行,并保留原始对象,以便保存这些代码的方法可以返回设置了所有附加信息的Mono
我正在努力解决这个问题。这种方法正确吗?一些帮助将不胜感激。一个简单的解决方案是不要将行平面映射,因为它将创建一个具有n元素(并键入行)的新发布者。在flatmap中,您可以启动另一个发布服务器,该发布服务器转到服务,设置数据,然后您可以返回原始对象
Mono<Basket> basketMono = Mono.just(basket)
.flatMap(b ->
Flux.fromIterable(b.items)
.flatMap(this::callService1)
.flatMap(this::callService2)
.then(Mono.just(b))
);
Mono basketMono=Mono.just(basket)
.flatMap(b->
流量可从项(b项)
.flatMap(this::callService1)
.flatMap(this::callService2)
.然后(单声道,只是(b))
);
我认为您的外部服务呼叫是被动的,类似这样:
Mono<Item> callService1(Item item) {
return mockService1().zipWith(Mono.just(item))
.map(it -> {
var result = it.getT2();
result.setInfo1(it.getT1());
return result;
});
}
Mono<String> mockService1() {
return Mono.just("some data " + ThreadLocalRandom.current().nextInt(100)).delayElement(Duration.ofMillis(100));
}
Mono呼叫服务1(项目){
返回mockService1().zipWith(Mono.just(item))
.map(it->{
var result=it.getT2();
result.setInfo1(it.getT1());
返回结果;
});
}
Mono mockService1(){
返回Mono.just(“some data”+ThreadLocalRandom.current().nextInt(100)).delayElement(Duration.ofMillis(100));
}
请注意,flatMap将自动订阅内部发布服务器
我还创建了一个简单的示例,您可以测试:
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class Example {
class Item {
String info1;
String info2;
public void setInfo1(String info1) {
this.info1 = info1;
}
public void setInfo2(String info2) {
this.info2 = info2;
}
public String getInfo1() {
return info1;
}
public String getInfo2() {
return info2;
}
}
class Basket {
String user;
List<Item> items;
public Basket(String user, List<Item> items) {
this.user = user;
this.items = items;
}
}
Mono<String> mockService1() {
return Mono.just("some data " + ThreadLocalRandom.current().nextInt(100)).delayElement(Duration.ofMillis(100));
}
Mono<String> mockService2() {
return Mono.just("some other data " + ThreadLocalRandom.current().nextInt(1000)).delayElement(Duration.ofMillis(100));
}
Mono<Item> callService1(Item item) {
return mockService1().zipWith(Mono.just(item))
.map(it -> {
var result = it.getT2();
result.setInfo1(it.getT1());
return result;
});
}
Mono<Item> callService2(Item item) {
return mockService2().zipWith(Mono.just(item))
.map(it -> {
var result = it.getT2();
result.setInfo1(it.getT1());
return result;
});
}
@Test
public void testBasket() {
var basket = new Basket("first", List.of(new Item(), new Item(), new Item()));
Mono<Basket> basketMono = Mono.just(basket)
.flatMap(b ->
Flux.fromIterable(b.items)
.flatMap(this::callService1)
.flatMap(this::callService2)
.then(Mono.just(b))
);
StepVerifier.create(basketMono)
.expectNextMatches(b -> b.items.get(0).info1 != null)
.verifyComplete();
}
}
import org.junit.jupiter.api.Test;
导入reactor.core.publisher.Flux;
导入reactor.core.publisher.Mono;
进口反应器、测试、步进校验器;
导入java.time.Duration;
导入java.util.List;
导入java.util.concurrent.ThreadLocalRandom;
公开课范例{
类项目{
字符串信息1;
字符串信息2;
公共void setInfo1(字符串info1){
this.info1=info1;
}
公共void setInfo2(字符串info2){
this.info2=info2;
}
公共字符串getInfo1(){
返回信息1;
}
公共字符串getInfo2(){
返回信息2;
}
}
班级篮{
字符串用户;
清单项目;
公共篮子(字符串用户、列表项){
this.user=用户;
这个项目=项目;
}
}
Mono mockService1(){
返回Mono.just(“some data”+ThreadLocalRandom.current().nextInt(100)).delayElement(Duration.ofMillis(100));
}
Mono mockService2(){
返回Mono.just(“其他一些数据”+ThreadLocalRandom.current().nextInt(1000)).delayElement(Duration.ofMillis(100));
}
Mono callService1(项目){
返回mockService1().zipWith(Mono.just(item))
.map(it->{
var result=it.getT2();
result.setInfo1(it.getT1());
返回结果;
});
}
Mono callService2(项目){
返回mockService2().zipWith(Mono.just(item))
.map(it->{
var result=it.getT2();
result.setInfo1(it.getT1());
返回结果;
});
}
@试验
公共无效测试篮(){
var basket=新篮子(“第一个”,列表中的(新项目(),新项目(),新项目());
Mono basketMono=Mono.just(篮子)
.flatMap(b->
流量可从项(b项)
.flatMap(this::callService1)
.flatMap(this::callService2)
.然后(单声道,只是(b))
);
StepVerifier.create(basketMono)
.expectNextMatches(b->b.items.get(0).info1!=null)
.verifyComplete();
}
}