Spring中如何将微服务获取的客户列表赋值给PeopleDTO的customers属性
实现步骤
1 先修正PeopleDTO类的基础问题
你当前定义的Customer是非静态内部类,实例化和JSON序列化时会依赖外部PeopleDTO实例,很容易出空指针或者序列化失败的问题,先调整类结构,同时加注解保证序列化结果和你预期的JSON结构匹配:
import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; import java.util.List; @Getter @Setter public class PeopleDTO { // 用JsonProperty对齐你预期返回的JSON字段名 @JsonProperty("type") private String processType; private String operation; private String entity; private String entityType; private Long id; @JsonProperty("documents") private Document document; // 必须加static修饰内部类 @Getter @Setter public static class Customer { // 类型和上游返回的数字类型对齐,避免类型转换异常 private Integer systemId; private String customerId; } // 对齐预期返回的relatedCustomers字段名 @JsonProperty("relatedCustomers") private List<Customer> customers; private Long idCuco; }
2 改造createPeople方法做字段转换
你现有getCuCoPerson返回的是响应式Mono<CuCoPerson>对象,优先推荐用全响应式写法组装对象,避免阻塞线程损耗性能,直接在map操作里完成数据转换即可:
// WebClientService类中新增/修改createPeople方法 public Mono<PeopleDTO> createPeople(Long id, String GS_AUTH_TOKEN) { // 先调用上游微服务获取过滤后的CuCoPerson数据 return getCuCoPerson(id.intValue(), GS_AUTH_TOKEN) .map(cuCoPerson -> { PeopleDTO people = new PeopleDTO(); // 赋值基础固定字段,值按你的业务要求调整 people.setProcessType("ONLINE"); people.setOperation("UPDATE"); people.setEntity("DOCUMENT"); people.setEntityType("NIE"); people.setId(id); people.setIdCuco(id); // Document对象按你的业务逻辑组装即可 people.setDocument(buildDocument(id)); // 核心:将上游返回的CustomerRelation列表转换为PeopleDTO的Customer列表 List<PeopleDTO.Customer> customerList = cuCoPerson.getRelatedCustomers() .stream() .map(relation -> { PeopleDTO.Customer customer = new PeopleDTO.Customer(); customer.setSystemId(relation.getSystemId()); customer.setCustomerId(relation.getCustomerId()); return customer; }) .collect(Collectors.toList()); people.setCustomers(customerList); return people; }); } // 抽离Document组装逻辑,按业务填值即可 private Document buildDocument(Long bizId) { Document document = new Document(); document.setId(bizId); // 此处补充additionals、code、typeDocument等字段的赋值逻辑 return document; }
3 调整控制器方法适配响应式返回
因为服务层返回的是Mono<PeopleDTO>,控制器直接返回这个Mono即可,不需要做额外的阻塞操作:
@GetMapping("/getId/{cucoId}") public Mono<PeopleDTO> getFullPeople(@PathVariable Long cucoId, @RequestHeader(value = "Authorization") String GS_AUTH_TOKEN) { return webClientService.createPeople(cucoId, GS_AUTH_TOKEN); }
可选兼容方案(不推荐)
如果你因为历史原因必须用同步方式返回PeopleDTO,可以在服务层调用Mono的block()方法同步拿到上游结果再做转换,注意这种写法会阻塞当前请求线程,性能比全响应式差很多:
// 同步版本仅作兼容参考 public PeopleDTO createPeopleSync(Long id, String GS_AUTH_TOKEN) { CuCoPerson cuCoPerson = getCuCoPerson(id.intValue(), GS_AUTH_TOKEN).block(); PeopleDTO people = new PeopleDTO(); // 基础字段、Document、customers的赋值逻辑和上面响应式版本完全一致 // ... return people; }
额外优化建议
- 你现在每次调用
getCuCoPerson都会新建一个WebClient实例,建议把WebClient定义成服务启动时初始化的单例Bean复用,能大幅减少连接创建开销,提升接口性能。 - 你已经在
getCuCoPerson里做过关联客户的规则过滤(systemId为300/400/410、customerId包含F),组装customers的时候直接拿过滤后的列表即可,不需要重复写过滤逻辑。
内容的提问来源于stack exchange,提问作者DiegoMG
相关产品推荐
相关产品推荐

