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
相关产品推荐
相关产品推荐

