如何用ModelMapper实现含多语言Map的实体到DTO的映射?
更优的ModelMapper多语言映射方案
针对你的多语言实体转DTO场景,有两种比PostConverter更便捷的实现方式:
方案1:自定义PropertyMap(直接高效)
PropertyMap可以精确定义源对象到目标对象的字段映射规则,避免手动逐个赋值,是这类场景最直接的解决方案。
实现步骤:
- 创建带目标语言参数的PropertyMap子类,在
configure方法中指定映射逻辑 - 将该PropertyMap注册到ModelMapper中
public class AToDTOMap extends PropertyMap<A, DTO> { private final String targetLang; public AToDTOMap(String targetLang) { this.targetLang = targetLang; } @Override protected void configure() { // 直接映射name字段 map().setName(source.getName()); // 从多语言Map中取指定语言的翻译,映射desc和content map(source.getTranslations().get(targetLang).getDesc()).setDesc(null); map(source.getTranslations().get(targetLang).getContent()).setContent(null); } } // 使用示例 ModelMapper modelMapper = new ModelMapper(); // 指定目标语言,比如英文 modelMapper.addMappings(new AToDTOMap("en")); A entityA = new A(); // 初始化entityA的name和translations数据... DTO dto = modelMapper.map(entityA, DTO.class);
方案2:Converter结合上下文传参(动态灵活)
如果需要频繁切换目标语言,不想重复创建PropertyMap,可以用Converter配合ModelMapper的上下文传递语言参数,实现动态映射。
实现步骤:
- 创建Converter,从上下文获取语言参数后完成映射
- 映射时通过RequestContext传入目标语言
// 定义Converter Converter<A, DTO> aToDTOConverter = context -> { A source = context.getSource(); String targetLang = context.getParameters().get("targetLang").toString(); DTO dto = new DTO(); dto.setName(source.getName()); ATranslation translation = source.getTranslations().get(targetLang); if (translation != null) { dto.setDesc(translation.getDesc()); dto.setContent(translation.getContent()); } return dto; }; // 注册Converter ModelMapper modelMapper = new ModelMapper(); modelMapper.addConverter(aToDTOConverter); // 动态指定语言映射 A entityA = new A(); // 初始化entityA数据... // 比如指定荷兰语 DTO dto = modelMapper.map(entityA, DTO.class, ctx -> ctx.addParameter("targetLang", "nl"));
关于之前Converter失效的说明
你提到Converter无法实现映射,通常是因为没有通过上下文传递语言参数,或者未将Converter正确注册到ModelMapper的TypeMap中。上述方案2展示了正确的Converter使用方式,通过上下文参数传递语言,即可实现动态映射。
内容的提问来源于stack exchange,提问作者SpazzMarticus
相关产品推荐
相关产品推荐

