Java中去除ResponseEntity<String>重复对象及解析空值排查
一、为什么performance变量始终为null?
核心原因是你的Java类结构和JSON的层级结构完全不匹配,导致Jackson无法正确反序列化JSON数据到PeriodData对象中,最终getCurrencyPerformanceList()返回null。我们来一步步拆解问题:
1. JSON结构与类结构的不匹配点
先看你的JSON顶级结构:
{ "AccountList": { "Accounts": [ ... ] }, "CurrencyPerformanceList": { "CurrencyPerformances": [ ... ] } }
而你的PeriodData类定义:
public class PeriodData { private List<String> accountList; // 错误:JSON里的AccountList是对象,不是String列表 private CurrencyPerformances CurrencyPerformanceList; // 错误:JSON里的CurrencyPerformanceList是包含数组的对象,不是CurrencyPerformances类实例 // ... getters/setters }
这里有两个致命错误:
accountList字段类型错误:JSON中的AccountList是一个包含Accounts数组的对象,不是List<String>;CurrencyPerformanceList字段类型错误:JSON中的CurrencyPerformanceList是一个包含CurrencyPerformances数组的对象,而你直接用CurrencyPerformances类来接收,层级完全不对。
2. 修正后的类结构
你需要按照JSON的层级定义对应的Java类,以下是核心类的示例(根据JSON字段补充完整字段即可):
顶级类PeriodData
public class PeriodData { // 对应JSON的"AccountList"对象 private AccountList AccountList; // 对应JSON的"CurrencyPerformanceList"对象 private CurrencyPerformanceList CurrencyPerformanceList; // Getters and Setters public AccountList getAccountList() { return AccountList; } public void setAccountList(AccountList accountList) { AccountList = accountList; } public CurrencyPerformanceList getCurrencyPerformanceList() { return CurrencyPerformanceList; } public void setCurrencyPerformanceList(CurrencyPerformanceList currencyPerformanceList) { CurrencyPerformanceList = currencyPerformanceList; } }
AccountList类(对应JSON的AccountList对象)
public class AccountList { // 对应JSON的"Accounts"数组 private List<Account> Accounts; // Getters and Setters public List<Account> getAccounts() { return Accounts; } public void setAccounts(List<Account> accounts) { Accounts = accounts; } }
Account类(对应每个账户对象)
public class Account { private Integer Id; private boolean IdSpecified; private String Number; // 补充JSON中所有Account字段... // Getters and Setters }
CurrencyPerformanceList类(对应JSON的CurrencyPerformanceList对象)
public class CurrencyPerformanceList { // 对应JSON的"CurrencyPerformances"数组 private List<CurrencyPerformance> CurrencyPerformances; // Getters and Setters public List<CurrencyPerformance> getCurrencyPerformances() { return CurrencyPerformances; } public void setCurrencyPerformances(List<CurrencyPerformance> currencyPerformances) { CurrencyPerformances = currencyPerformances; } }
CurrencyPerformance类(对应每个CurrencyPerformance对象)
public class CurrencyPerformance { private String Currency; private PerformanceList PerformanceList; // Getters and Setters public String getCurrency() { return Currency; } public void setCurrency(String currency) { Currency = currency; } public PerformanceList getPerformanceList() { return PerformanceList; } public void setPerformanceList(PerformanceList performanceList) { PerformanceList = performanceList; } }
补充PerformanceList和Performance类
按照JSON中的层级,继续定义PerformanceList(包含Performances数组)和Performance类,确保每个字段和JSON中的键对应(注意大小写,如果Java用小驼峰,JSON用大驼峰,可添加@JsonProperty("XXX")注解指定键名)。
3. 修正后的反序列化代码
类结构修正后,你的代码就能正确获取到CurrencyPerformanceList:
PeriodData periodData = objectMapper.readValue( performanceQueryService.getAggregatedAccountPerformances(req).getBody(), PeriodData.class ); CurrencyPerformanceList performance = periodData.getCurrencyPerformanceList(); // 此时performance不再为null
二、如何去除ResponseEntity中的重复对象?
要去除重复对象,我们需要先将JSON反序列化为Java对象,去重后再序列化回JSON(如果需要)。步骤如下:
1. 定义重复判断规则
首先要明确:什么是“重复对象”?比如:
- 对于
Accounts数组:是否Id相同即为重复? - 对于
Performances数组:是否StartDate+EndDate+Currency组合相同即为重复?
根据业务规则,选择合适的判断依据。
2. 针对不同数组的去重实现
示例1:基于字段去重(比如Account的Id)
如果以Account.Id作为唯一标识去重,可以用Collectors.toMap实现:
// 获取AccountList并去重 AccountList accountList = periodData.getAccountList(); List<Account> uniqueAccounts = accountList.getAccounts().stream() // 以Id为键,保留第一个出现的对象 .collect(Collectors.toMap(Account::getId, account -> account, (existing, newAccount) -> existing)) .values() .stream() .collect(Collectors.toList()); // 更新去重后的列表 accountList.setAccounts(uniqueAccounts);
示例2:基于对象全量相等去重(重写equals和hashCode)
如果需要判断对象的所有字段都相同才视为重复,可以在对应的类(比如Account)中重写equals和hashCode方法,然后用distinct():
// 先在Account类中重写equals和hashCode List<Account> uniqueAccounts = accountList.getAccounts().stream() .distinct() .collect(Collectors.toList()); accountList.setAccounts(uniqueAccounts);
示例3:对CurrencyPerformances数组去重
同理,针对CurrencyPerformanceList中的CurrencyPerformances数组,比如以Currency为唯一标识去重:
CurrencyPerformanceList performanceList = periodData.getCurrencyPerformanceList(); List<CurrencyPerformance> uniquePerformances = performanceList.getCurrencyPerformances().stream() .collect(Collectors.toMap(CurrencyPerformance::getCurrency, p -> p, (existing, newP) -> existing)) .values() .stream() .collect(Collectors.toList()); performanceList.setCurrencyPerformances(uniquePerformances);
3. 序列化回JSON(可选)
如果需要将去重后的对象重新转为JSON字符串:
String deduplicatedJson = objectMapper.writeValueAsString(periodData);
内容的提问来源于stack exchange,提问作者Anuja Patil

