遍历Flux <T>并使用Webclient获取数据

时间:2019-12-14 21:02:54

标签: reactive-programming spring-webflux

我正在尝试从另一个微服务中获取数据。假设您有三种微服务:州,学校和学生。您可以从SchoolRepository通过stateId获得Flux ,并且对于每个要通过Web客户端调用Student微服务的学校,该客户端返回Flux 并将其设置为Flux 。很快,我想做的是:

public Flux<School> getBySchool(Long stateId){

        Flux<School> schoolList=schoolRepository.findByStateId(stateId);
        //And for each school I want to do this
                Flux<Student> studentsfound=webClient.get().uri("bla bla bla"+school.getSchoolId).exchange().flatMapMany(response->response.bodyToFlux(Student.class));
                //I have a List<Student> entity in School domain, so I want Flux<Student> --> List<Student> and add it to School. Something like school.setStudentList(studentListReturned).
        //And then return Flux<Stundent>
}

如何遍历Flux ,并在获得Flux 之后如何将其添加到适当的Flux 中?预先谢谢你。

更新

解决方案

非常感谢@ K.Nicholas。我可以按照以下方式解决问题,但欢迎使用更优雅的解决方案。我正在控制器中订阅schoolList,因为我必须将Flux 从服务层返回到控制器层。

public Flux<School> getBySchoolWithStudents(Long stateId) {
    Flux<School> schoolList = schoolRepository.findByStateId(stateId);
    return schoolList.flatMap(school -> {
        Flux<Student> studentFlux = webClientBuilder.build().get().uri(REQUEST_URI + school.getSchoolId()).exchange().flatMapMany(response -> response.bodyToFlux(Student.class));
        return studentFlux.collectList().map(list -> {
            school.setStudentList(list);
            return school;
        });
    });
}

1 个答案:

答案 0 :(得分:0)

编辑:第二次尝试。因此,我看不到什么特别的东西。使用collectList方法并在map函数中分配它。 map函数返回范围内的学校对象。我必须进行一些调试,以确保我的类正确支持序列化/反序列化。

    WebClient.create().get().uri(URI.create("http://localhost:8082/ss/school?state=CA"))
    .accept(MediaType.APPLICATION_JSON)
    .exchange()
    .flatMapMany(cr->cr.bodyToFlux(School.class))
    .flatMap(school->{
        return WebClient.create().get().uri(URI.create("http://localhost:8081/ss/student?school="+school.getName()))
        .accept(MediaType.APPLICATION_JSON)
        .exchange()
        .flatMapMany(crs->crs.bodyToFlux(Student.class))
        .collectList()
        .map(sl->{
            school.setStudents(sl);
            return school;
        });
    })
    .subscribe(System.out::println);