如何优雅实现不同API的DTO到标准DTO的字段映射转换?
多异构API DTO转标准DTO的优雅实现方案
你当前通过转Map修改键名的方式虽然能实现需求,但存在类型不安全、易出错、维护成本高的问题,推荐以下几种更优雅的实现方式:
1. 编译期映射:MapStruct(性能最优、类型安全)
首先定义你的标准DTO:
class StandardCar { private String make; private int manufactureYear; private String colour; // 省略getter/setter }
然后编写MapStruct的映射接口,通过注解指定字段映射关系:
import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @Mapper public interface CarMapper { // 单例实例,直接调用即可 CarMapper INSTANCE = Mappers.getMapper(CarMapper.class); // 映射Volkswagen到StandardCar,指定字段对应关系 @Mapping(source = "model", target = "make") @Mapping(source = "year", target = "manufactureYear") StandardCar convertVolkswagenToStandard(Volkswagen volkswagen); // BMW与StandardCar字段匹配度高,无需额外配置 StandardCar convertBmwToStandard(BMW bmw); }
使用时直接调用映射方法:
Volkswagen vw = new Volkswagen(); vw.setModel("Beetle"); vw.setYear(1990); vw.setColour("Blue"); StandardCar standardCar = CarMapper.INSTANCE.convertVolkswagenToStandard(vw);
优势:编译期自动生成原生Java转换代码,无反射开销;类型安全,编译时就能发现字段不匹配问题;支持自定义转换逻辑,维护成本低。
2. 运行期映射:ModelMapper(配置简单、快速开发)
ModelMapper通过反射自动匹配字段,只需为差异字段配置映射规则:
import org.modelmapper.ModelMapper; // 初始化并配置映射规则 ModelMapper modelMapper = new ModelMapper(); modelMapper.typeMap(Volkswagen.class, StandardCar.class) .addMapping(Volkswagen::getModel, StandardCar::setMake) .addMapping(Volkswagen::getYear, StandardCar::setManufactureYear); // 转换示例 Volkswagen vw = new Volkswagen(); // 赋值操作... StandardCar standardVw = modelMapper.map(vw, StandardCar.class); // BMW直接自动映射 BMW bmw = new BMW(); StandardCar standardBmw = modelMapper.map(bmw, StandardCar.class);
优势:无需编写大量手动转换代码,配置灵活;适合快速搭建原型或字段差异较少的场景。缺点:运行期反射带来一定性能开销,类型安全依赖运行时校验。
3. 手动编写转换器(完全可控、无依赖)
如果不想引入第三方依赖,可以为每个异构DTO编写专属转换器:
class VolkswagenConverter { public static StandardCar convert(Volkswagen vw) { if (vw == null) { return null; } StandardCar car = new StandardCar(); car.setMake(vw.getModel()); car.setManufactureYear(vw.getYear()); car.setColour(vw.getColour()); return car; } } class BMWConverter { public static StandardCar convert(BMW bmw) { if (bmw == null) { return null; } StandardCar car = new StandardCar(); car.setMake(bmw.getMake()); car.setManufactureYear(bmw.getManufactureYear()); car.setColour(bmw.getColour()); return car; } }
使用时直接调用静态转换方法:
StandardCar standardCar = VolkswagenConverter.convert(vw);
优势:完全控制转换逻辑,无第三方依赖,性能最优;缺点:需要手动维护每个转换器,当DTO字段变更时需同步修改。
内容的提问来源于stack exchange,提问作者z.x.99
相关产品推荐
相关产品推荐

