简体   繁体   中英

How to convert Mono object to other Mono object in Spring Webflux

I have a class like this

public class Person {
      private String name;
      private String age;
      private Boolean student;
      ...
      //
      getters and setters
}
public class PersonDto {
      private List<Person> persons
      private Person president
      //
      getters and setters
}

and get data to webclient from external API

--- omitted ---
final Mono<PersonDto> personDto = wrapperWebClient.getPersonDto(uriComponents, params, PersonDto.class);
Mono<StudentDto> studentDto = convert(personDto);
--- omitted ---

and I want to transform data Mono DTO like below.

public class Student {
      // no constructors 
      private String name;
      private String age;
      private Boolean student;
      ...
      //
      getters and setters
}
public class StudentDto {
      private List<Student> students;
      private Student represent;
      ...
      //
      getters and setters
}

it's my try

--- omitted ---
private Mono<StudentDto> convert(Mono<PersonDto> personDto) {
      StudentDto studentDto = new StudentDto();
      personDto.map(
          persons -> {
              studentDto.setStudents(
                      persons.getPersons()
                       .stream().filter(person -> person.isStudent())
                       .collect(toList())
              );
              studentDto.setRepresent(
                      persons.getRepresent().isStudent()
              );
          }
      )
      return ???;
} 

My approach seems to be synchronous.

you use flatMap . This is basic reactor and you should read through the Getting started reactor before asking on stack overflow.

private Mono<StudentDto> convert(Mono<PersonDto> personDto) {
    return personDto.flatMap(personDto -> {
                final StudentDto studentDto = new StudentDto();
                studentDto.setStudents(
                        persons.getPersons()
                         .stream().filter(person -> person.isStudent())
                         .collect(toList())
                );
                studentDto.setRepresent(
                        persons.getRepresent().isStudent()
                );
                return Mono.just(studentDto);
            })
} 

Just return Mono with map

private Mono<StudentDto> convert(Mono<PersonDto> personDto) {
      return personDto.map(
          persons -> {
              StudentDto studentDto = new StudentDto();
              studentDto.setStudents(
                      persons.getPersons()
                       .stream().filter(person -> person.isStudent())
                       .collect(toList())
              );
              studentDto.setRepresent(
                      persons.getRepresent().isStudent()
              );
          }
      );
} 

The main difference between map and flatMap is synchronicity .

If you want handle another asynchronous one, use flatMap .

Or, if you just want to reformat the output of the Mono/Flux , use map .

There is transform method in Mono class.

return Mono.fromFuture(step1.callFuture(input))
           .doOnSuccess(this::logJsonInput)
           .transform(otherService::calculate);

where

OtherService {
   public Mono<Result> calculate(Mono<Step1Output> input) {
        //...
   }       
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM