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

Java中如何将List<Object>映射为自定义对象并序列化为指定JSON结构

问题根因

你执行的泛型强制转换仅在编译期生效,运行时不会校验列表内的元素类型。internalRepo.getAllCustomerData()实际返回的是List<Object[]>类型,你只是把它强转成了表面的List<CustomerDataDTO>,列表内存储的仍然是数组对象而非DTO实例,因此Jackson序列化后会输出二维数组结构。

解决方案

方案1:手动转换原始数组到DTO实例(无额外依赖、无需修改现有查询逻辑)

首先遍历原始数组列表,逐个封装为CustomerDataDTO实例后再序列化:

// 先拿到原始数组列表
List<Object[]> rawList = (List<Object[]>) internalRepo.getAllCustomerData();
// 转换为DTO列表
List<CustomerDataDTO> dtoList = rawList.stream().map(item -> {
    CustomerDataDTO dto = new CustomerDataDTO();
    // 按数组下标对应赋值,注意类型匹配
    dto.setCust_file_id((Long) item[0]);
    dto.setCustomerName((String) item[1]);
    return dto;
}).toList();
// 序列化DTO列表即可得到目标结构
String result = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(dtoList);

方案2:修改JPA查询直接返回DTO实例(适合Spring Data JPA场景)

第一步先给CustomerDataDTO添加全参数构造方法:

public class CustomerDataDTO {
    private Long cust_file_id;
    private String customerName;
    // 新增全参构造
    public CustomerDataDTO(Long cust_file_id, String customerName) {
        this.cust_file_id = cust_file_id;
        this.customerName = customerName;
    }
    // 原有getters、setters保持不变
}

第二步修改Repository的查询方法,使用构造函数表达式直接映射DTO:

// 注意替换成你自己的DTO全类名、实体类对应字段名
@Query("SELECT new com.xxx.xxx.CustomerDataDTO(c.cust_file_id, c.customerName) FROM 你的实体类名 c")
List<CustomerDataDTO> getAllCustomerData();

改完后直接调用该方法返回的就是真实的DTO实例列表,直接序列化即可得到目标结果。

注意事项

如果你的CustomerDataDTO的getter方法是标准驼峰命名(如getCustFileId()而非getCust_file_id()),需要在对应字段上加@JsonProperty注解指定序列化后的key,保证输出符合你的预期:

public class CustomerDataDTO {
    @JsonProperty("cust_file_id")
    private Long cust_file_id;
    private String customerName;
    // 构造、getter、setter
}

内容的提问来源于stack exchange,提问作者Arvind Reddy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:36:00