You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot(Java21)实现Map/List<Map>到DTO的自定义映射与类型转换

通用Map/List转DTO/List的Spring Bean实现方案

1. 依赖选择与引入

优先选用ModelMapper(轻量易配置,适合快速实现),也可选择MapStruct(编译期生成转换代码,性能更优)。以下是ModelMapper的依赖配置:

Maven

<dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>3.2.0</version> <!-- 最新稳定版 -->
</dependency>

Gradle

implementation 'org.modelmapper:modelmapper:3.2.0'

2. 自定义映射规则配置

针对Map键名与DTO属性名不匹配的场景,通过ModelMapper的TypeMap预定义映射规则,统一配置在Spring配置类中:

import org.modelmapper.ModelMapper;
import org.modelmapper.TypeMap;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DtoMappingConfig {

    @Bean
    public ModelMapper modelMapper() {
        ModelMapper modelMapper = new ModelMapper();
        
        // 示例:UserDTO的自定义映射(Map的"user_name"对应DTO的"username","age_str"转Integer类型的"age")
        TypeMap<Map<String, Object>, UserDTO> userDtoTypeMap = modelMapper.createTypeMap(Map.class, UserDTO.class);
        userDtoTypeMap.addMappings(mapper -> {
            mapper.map(src -> src.get("user_name"), UserDTO::setUsername);
            // 数值类型转换:String转Integer
            mapper.map(src -> Integer.parseInt(src.get("age_str").toString()), UserDTO::setAge);
        });
        
        // 可添加更多DTO的映射规则
        return modelMapper;
    }
}

3. 实现通用转换Spring Bean

封装通用转换工具类,作为Spring Bean提供批量/单个转换方法,同时支持动态添加映射规则:

import org.modelmapper.ModelMapper;
import org.modelmapper.TypeMap;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@Component
public class GenericDtoConverter {

    private final ModelMapper modelMapper;

    public GenericDtoConverter(ModelMapper modelMapper) {
        this.modelMapper = modelMapper;
    }

    /**
     * 单个Map转DTO
     */
    public <T> T convertMapToDto(Map<String, Object> map, Class<T> dtoClass) {
        return modelMapper.map(map, dtoClass);
    }

    /**
     * List<Map>转List<DTO>
     */
    public <T> List<T> convertMapListToDtoList(List<Map<String, Object>> mapList, Class<T> dtoClass) {
        return mapList.stream()
                .map(map -> convertMapToDto(map, dtoClass))
                .collect(Collectors.toList());
    }

    /**
     * 动态添加自定义映射规则(适用于临时/运行时配置)
     */
    public <T> void addCustomMapping(Class<T> dtoClass, Consumer<TypeMap<Map<String, Object>, T>> mappingConsumer) {
        TypeMap<Map<String, Object>, T> typeMap = modelMapper.createTypeMap(Map.class, dtoClass);
        mappingConsumer.accept(typeMap);
    }
}

4. 数值类型转换增强配置

如需全局统一处理数值类型自动转换(如String转Number、Number类型互转),在DtoMappingConfig的modelMapper()方法中添加自定义转换器:

// 全局数值类型转换器
modelMapper.addConverter(context -> {
    Object source = context.getSource();
    if (source == null) return null;
    Class<?> targetType = context.getDestinationType();
    
    // String转Integer/Long/Double
    if (source instanceof String strValue) {
        if (targetType == Integer.class) return Integer.parseInt(strValue);
        if (targetType == Long.class) return Long.parseLong(strValue);
        if (targetType == Double.class) return Double.parseDouble(strValue);
    }
    
    // Number类型互转
    if (source instanceof Number numValue) {
        if (targetType == Integer.class) return numValue.intValue();
        if (targetType == Long.class) return numValue.longValue();
        if (targetType == Double.class) return numValue.doubleValue();
    }
    return source;
});

5. 使用示例

定义DTO

public class UserDTO {
    private String username;
    private Integer age;
    private Double score;

    // Getter、Setter、toString方法省略
}

在业务类中调用转换器

import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class UserService {

    private final GenericDtoConverter dtoConverter;

    public UserService(GenericDtoConverter dtoConverter) {
        this.dtoConverter = dtoConverter;
    }

    public UserDTO processSingleUserMap(Map<String, Object> userMap) {
        return dtoConverter.convertMapToDto(userMap, UserDTO.class);
    }

    public List<UserDTO> processUserMapList(List<Map<String, Object>> userMapList) {
        return dtoConverter.convertMapListToDtoList(userMapList, UserDTO.class);
    }
}

备选方案:MapStruct

若追求极致性能(无反射开销),可替换为MapStruct:

  1. 引入MapStruct核心依赖与注解处理器
  2. 定义通用转换接口并添加@Mapper注解
  3. 通过@Mapping配置字段映射与类型转换规则

内容的提问来源于stack exchange,提问作者Basharat Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:27:20