Java MapStruct如何编写通用枚举转换器解决枚举映射报错
问题根因
你的代码存在两个核心问题,导致MapStruct无法识别转换逻辑:
- 基础枚举代码存在语法错误:
Type枚举中TEST1、TEST2重写的convertToINT方法返回值定义为Type类型,和抽象方法声明的返回值TypeIntegration冲突,且返回的Type.INTEGRATION1本身不存在(INTEGRATION1属于TypeIntegration枚举) - 自定义转换方法签名不符合MapStruct的匹配规则:你写的泛型方法带了两个入参,MapStruct匹配单属性转换方法时,只会自动识别入参为源属性类型、返回值为目标属性类型的单参数方法,额外加的
@TargetType标注的参数会被识别为映射上下文参数,无法自动注入,哪怕加了@Named和qualifiedByName也会匹配失败。
正确实现方案
步骤1:修正枚举代码并定义通用转换接口
首先定义一个通用的枚举转换标记接口,所有需要自动转换的源枚举都实现该接口,后续新增枚举类型不需要重复写转换逻辑:
/** * 标记可自动转换为目标枚举的源枚举 * @param <T> 目标枚举类型 */ public interface EnumConvertible<T extends Enum<T>> { T convertToINT(); }
修正Type枚举的代码错误,实现上述接口:
public enum Type implements EnumConvertible<TypeIntegration>{ TEST1{ @Override public TypeIntegration convertToINT() { return TypeIntegration.INTEGRATION1; } }, TEST2{ @Override public TypeIntegration convertToINT() { return TypeIntegration.INTEGRATION2; } }, TEST3{ @Override public TypeIntegration convertToINT(){ return TypeIntegration.INTEGRATION3; } }; } public enum TypeIntegration { INTEGRATION1, INTEGRATION2, INTEGRATION3 }
同时修正DTO类的Java命名规范问题(类名首字母大写,避免MapStruct扫描时出现匹配问题):
@Getter @Setter public class TypeSaveReqDto{ private Object blabla; private Object blabla2; private Type type; } @Getter @Setter public class TypeIntegrationObject{ private Object blabla; private Object blabla2; private TypeIntegration type; }
步骤2:编写通用枚举转换器
写单参数的通用转换方法,MapStruct在编译期会自动匹配符合入参、返回值类型的方法:
@Mapper(componentModel = "spring") public class EnumMapper { public <S extends EnumConvertible<T>, T extends Enum<T>> T convert(S source) { return source == null ? null : source.convertToINT(); } }
步骤3:配置业务Mapper
在业务Mapper中引入通用枚举转换器即可,不需要单独为枚举字段加@Mapping注解,MapStruct会自动识别类型匹配的转换方法:
@Mapper(componentModel = "spring", uses = EnumMapper.class) public interface TypeReqMapper { TypeIntegrationObject typeSaveReqDtoToTypeIntegrationObject(TypeSaveReqDto typeSaveReqDto); }
补充说明
- 该方案是真正通用的实现,后续如果新增其他需要互转的枚举对,只需要让源枚举实现
EnumConvertible接口、指定目标枚举类型、实现转换逻辑即可,不需要修改EnumMapper的代码 - 如果你确实需要针对特定枚举做特殊转换,只需要在
EnumMapper中追加对应入参、返回值类型的转换方法,MapStruct会优先匹配类型更具体的方法 - 编译后可以查看MapStruct生成的实现类代码,确认枚举转换逻辑是否正确调用了
convertToINT方法
内容的提问来源于stack exchange,提问作者Sencer Seven
相关产品推荐
相关产品推荐

