使用MapStruct映射DTO时如何为返回JSON新增额外父节点
方案推荐
方案1:创建通用组合响应DTO(优先推荐)
这是最规范、可维护性最高的实现方式,不会引入额外序列化配置,也方便后续全接口统一扩展:
- 首先定义通用响应封装类,支持泛型适配所有接口返回:
@Data public class CommonResponse<T> { private T data; @JsonProperty("data_flags") private List<String> dataFlags = new ArrayList<>(); // 初始化默认空集合,避免返回null }
- 移除
HumanMoodOutputDto上的@JsonRootName(value = "data")注解,避免后续序列化多嵌套一层data节点。 - 修改控制器的返回类型与组装逻辑,将业务数据和告警信息分别填充到对应字段:
@PostMapping("humanMood") public Mono<CommonResponse<HumanMoodOutputDto>> getHumanMood( @Valid @RequestBody Mono<HumanMoodInputDto> humanMoodInputDto) { return humanMoodService.create(humanMoodInputDto.map(mapper::dtoToPushedInput)) .map(pushedOutput -> { CommonResponse<HumanMoodOutputDto> resp = new CommonResponse<>(); resp.setData(mapper.outputToDto(pushedOutput)); // 填充映射错误、告警信息,没有的话默认返回空数组 resp.setDataFlags(pushedOutput.getErrorFlags()); return resp; }); }
优点:类型安全、可复用性高,后续如果需要统一新增返回码、响应消息等公共字段,直接修改CommonResponse即可,不需要调整各业务接口的DTO。
方案2:直接用Map封装返回(仅适合临时应急场景)
如果不想新增DTO类,可以直接用Map<String, Object>作为返回值类型,手动封装两个节点:
@PostMapping("humanMood") public Mono<Map<String, Object>> getHumanMood( @Valid @RequestBody Mono<HumanMoodInputDto> humanMoodInputDto) { return humanMoodService.create(humanMoodInputDto.map(mapper::dtoToPushedInput)) .map(pushedOutput -> { Map<String, Object> resp = new HashMap<>(); resp.put("data", mapper.outputToDto(pushedOutput)); resp.put("data_flags", Optional.ofNullable(pushedOutput.getErrorFlags()).orElse(new ArrayList<>())); return resp; }); }
缺点:无类型校验,容易出现字段拼写错误,后续维护成本高,不建议长期使用。
内容的提问来源于stack exchange,提问作者Airidas36
相关产品推荐
相关产品推荐

