我正在将代码从命令式迁移到响应式Java。
在命令式编程中,我们将重要信息保存在DTO / Context中并随请求传递,是否有一种方法可以使用spring-webflux / project-reactor在反应堆范式中实现相同的目标?
换句话说::除了非阻塞调用序列之外,我如何才能保持所需的值。
例如,假设我有Employee和Department mongo集合,并使用反应性mongo存储库从数据库中获取结果。
empId
状态:ACTIVE |不活跃
empName
empAge
managerId
deptIds
deptId
deptName
Flux<Employee> empFlux = empRepository.findEmployees("ACTIVE"); // (1)
Flux<Department> deptFlux= deptRepository.findDepartments(deptIds); // (2)
webclient (empId, managerId, deptId, deptName); // (3)
我用谷歌搜索似乎可以使用平面图对这些流程进行排序,但是每次转换时,我都会在上次调用中丢失信息。
就像上面的代码一样:
(1):获取活动员工的列表
(2):使用ID的平面图,我们可以获得合格部门的列表,但丢失了有关员工的信息。
(3)我需要使用有关employee,dept的信息对Webclient进行响应式休息呼叫。
我的问题是如何在无阻塞通量和Monos序列中保留此信息。
答案 0 :(得分:0)
在这种情况下,元组很有用:
empRepository.findEmployees("ACTIVE")
.flatMap(emp -> deptRepository.findDepartments(emp.getDeptIds()).map(dept -> Tuples.of(emp,dept)))
.flatMap(tuple -> webclient(tuple.getT1().getEmpId(), tuple.getT1().getMangagerId(), tuple.getT2().getDeptId(), tuple.getT2().getDeptName()));
IMO的可读性不高,但它也适用于某些官方运营商(如zip
)的Reactor Way™。
答案 1 :(得分:0)
您还可以像这样使用zipwith运算符:
Flux<WebClientReturn> infoFlux = empRepository.findEmployees("ACTIVE")
.zipWith(deptRepository.findDepartments(deptIds), (employee, dept) -> {
webclient (employee.getempId(), employee.getmanagerId(), dept.getdeptId(), dept.getdeptName());
})
我认为这是最具描述性和最易读的方式。
答案 2 :(得分:-1)
您需要将该信息保存在单独的容器中,例如数组,列出可以访问的信息,并在需要时使用它。您可以尝试如下操作。
// Declare the arraylist to contain the return response object.
List<Object> returnedObjectList = new ArrayList<>();
Flux<Employee> empFlux = empRepository.findEmployees("ACTIVE"); // (1)
Flux<Department> deptFlux= deptRepository.findDepartments(deptIds); // (2)
return Flux.zip(empFlux, deptFlux)
.flatMap(tuple -> {
final String empId = tuple.getT1().getEmpId();
final String managerId = tuple.getT1().getManagerId();
final String deptId = tuple.getT2().getDeptId();
final String deptName = tuple.getT2().getDeptName();
Object returnedObject = webclient(empId, managerId, deptId, deptName); // (3)
returnedObjectList.add(returnedObject);
return Flux.just(returnedObject);
});