Spring Webflux中如何将Mono<PersonDto>转换为Mono<StudentDto>
正确实现方案
你原来的写法主要存在三个问题:在map算子外部初始化StudentDto存在线程安全隐患、map的回调逻辑没有返回值、缺少Person到Student的类型转换步骤,以下是符合响应式规范的实现:
1. 先实现Person到Student的属性转换
因为两个类是独立类型,哪怕字段完全一致也不能直接赋值,需要单独做属性映射:
// 也可以直接使用MapStruct、ModelMapper等映射框架自动生成转换逻辑 private Student convertPersonToStudent(Person person) { Student student = new Student(); student.setName(person.getName()); student.setAge(person.getAge()); student.setStudent(person.getStudent()); // 其他属性按需拷贝 return student; }
2. 实现响应式转换方法
所有转换逻辑放在map算子内部执行,直接返回转换后的Mono<StudentDto>即可:
private Mono<StudentDto> convert(Mono<PersonDto> personDtoMono) { return personDtoMono.map(personDto -> { StudentDto studentDto = new StudentDto(); // 转换学生列表:先过滤学生身份,再做类型转换 List<Student> students = personDto.getPersons() .stream() // 用Boolean.TRUE.equals避免字段为null时空指针 .filter(person -> Boolean.TRUE.equals(person.getStudent())) .map(this::convertPersonToStudent) .toList(); studentDto.setStudents(students); // 转换代表:判断president是否为学生,是则转换赋值 if (Boolean.TRUE.equals(personDto.getPresident().getStudent())) { studentDto.setRepresent(convertPersonToStudent(personDto.getPresident())); } else { // 非学生的代表字段赋值逻辑可按业务需求调整 studentDto.setRepresent(null); } return studentDto; }); }
实现说明
- 所有转换逻辑都在
map的回调函数内部执行,全程异步非阻塞,完全符合WebClient的响应式编程模型 StudentDto实例在map回调内部创建,不存在跨线程共享变量,规避了线程安全问题map算子会自动把你返回的StudentDto对象包装为Mono<StudentDto>,直接返回map操作后的结果即可
原代码的问题补充
- 原代码中
PersonDto的属性是president,你调用getRepresent()属于笔误,会直接编译失败 - 原代码直接把
Person类型的集合赋值给Student类型的List,存在类型不兼容问题,必须做显式转换 - 原代码
map的回调没有返回值,不符合map算子要求传入有返回值的函数的规则,且你没有把map操作后的Mono作为返回值,自然不知道该返回什么内容
内容的提问来源于stack exchange,提问作者EdgarHan
相关产品推荐
相关产品推荐

