如何创建通用ModelMapper管理抽象类实现Spring REST API的Entity与DTO互转
错误原因
Java的泛型存在类型擦除机制,运行时Entity和DTO这两个泛型参数的具体类型信息会被擦除,Entity.class属于语法错误,编译器无法获取到泛型参数的实际类对象,所以直接抛出Illegal class literal for the type parameter Entity异常。
正确实现方案
我们可以通过在抽象类的构造方法中接收实际的Entity、DTO类对象,由子类实例化时传入具体类型的方式解决这个问题,完整实现如下:
1. 抽象转换类代码
import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; import java.util.stream.Collectors; public abstract class AbstractConverter<Entity, DTO> { @Autowired private ModelMapper modelMapper; private final Class<Entity> entityClass; private final Class<DTO> dtoClass; // 构造方法要求子类传入实际的类型Class protected AbstractConverter(Class<Entity> entityClass, Class<DTO> dtoClass) { this.entityClass = entityClass; this.dtoClass = dtoClass; } // DTO转Entity public Entity toEntity(DTO dto) { return modelMapper.map(dto, entityClass); } // Entity转DTO public DTO toDTO(Entity entity) { return modelMapper.map(entity, dtoClass); } // 批量转换Entity列表为DTO列表 public List<DTO> toDTOList(List<Entity> entityList) { return entityList.stream() .map(item -> modelMapper.map(item, dtoClass)) .collect(Collectors.toList()); } // 批量转换DTO列表为Entity列表 public List<Entity> toEntityList(List<DTO> dtoList) { return dtoList.stream() .map(item -> modelMapper.map(item, entityClass)) .collect(Collectors.toList()); } }
2. 子类使用示例
只需继承该抽象类,在构造方法中传入对应实体和DTO的Class对象即可,不需要重复实现转换逻辑:
import org.springframework.stereotype.Component; // 示例:User实体和UserDTO的转换器 @Component public class UserConverter extends AbstractConverter<User, UserDTO> { public UserConverter() { // 传入实际的Entity和DTO的Class super(User.class, UserDTO.class); } }
3. 调用示例
@Autowired private UserConverter userConverter; // 单对象转换 User user = userConverter.toEntity(userDTO); UserDTO dto = userConverter.toDTO(user); // 批量转换 List<UserDTO> dtoList = userConverter.toDTOList(userList);
补充说明
注意:你需要提前将ModelMapper注册到Spring容器中,示例配置如下:
import org.modelmapper.ModelMapper; import org.modelmapper.config.AccessLevel; import org.modelmapper.convention.MatchingStrategies; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ModelMapperConfig { @Bean public ModelMapper modelMapper() { ModelMapper modelMapper = new ModelMapper(); // 可按需调整配置:匹配策略、字段访问权限等 modelMapper.getConfiguration() .setMatchingStrategy(MatchingStrategies.STRICT) .setFieldMatchingEnabled(true) .setFieldAccessLevel(AccessLevel.PRIVATE); return modelMapper; } }
如果需要自定义特殊字段的映射规则,可以直接在对应的Converter子类中重写对应的转换方法即可。
内容的提问来源于stack exchange,提问作者Luca De Salve
相关产品推荐
相关产品推荐

