复杂JSON数组转Java POJO类的序列化异常问题排查
解决Jackson序列化POJO到JSON的两个问题
问题总结
序列化后出现两处不符合预期的异常:
roomsInfo被序列化为单个对象,而非预期的数组结构kidsAges字段输出异常的"10": null格式,而非正常的数组
问题原因与修复方案
1. 修复roomsInfo非数组的问题
预期JSON中roomsInfo是数组类型,但当前Example类里定义的roomsInfo是单个RoomsInfo对象,而非集合类型,导致Jackson无法序列化为数组。
修改Example类代码:
将单个对象类型改为List<RoomsInfo>,同步更新构造方法、getter和setter:
import java.util.List; public class Example { private String checkIn; private String checkOut; // 从单个对象改为集合 private List<RoomsInfo> roomsInfo; private Object searchInfo; private Object crossSellDetail; private String query; // 构造方法参数同步改为List类型 public Example(String checkIn, String checkOut, List<RoomsInfo> roomsInfo, Object searchInfo, Object crossSellDetail, String query) { super(); this.checkIn = checkIn; this.checkOut = checkOut; this.roomsInfo = roomsInfo; this.searchInfo = searchInfo; this.crossSellDetail = crossSellDetail; this.query = query; } // 其他原有getter/setter不变,仅修改roomsInfo相关方法 public List<RoomsInfo> getRoomsInfo() { return roomsInfo; } public void setRoomsInfo(List<RoomsInfo> roomsInfo) { this.roomsInfo = roomsInfo; } // 省略其余getter/setter }
2. 修复kidsAges字段异常的问题
RoomsInfo构造方法的参数名是list,但对应字段是kidsAges,Jackson默认会根据构造方法参数名推断序列化键名,导致出现异常的"10": null。
修复方案(二选一):
方案A:统一构造方法参数名与字段名
直接修改构造方法参数名,和字段名kidsAges保持一致:
// 修改RoomsInfo的构造方法 public RoomsInfo(int adultsCount, List<Integer> kidsAges) { super(); this.adultsCount = adultsCount; this.kidsAges = kidsAges; }
方案B:添加注解指定字段名
如果不想修改参数名,给构造方法参数加上@JsonProperty注解明确对应字段:
import com.fasterxml.jackson.annotation.JsonProperty; // 修改RoomsInfo构造方法 public RoomsInfo(int adultsCount, @JsonProperty("kidsAges") List<Integer> list) { super(); this.adultsCount = adultsCount; this.kidsAges = list; }
3. 调整测试代码UserInfo
由于Example构造方法现在接收List<RoomsInfo>,需要把单个RoomsInfo对象放入集合中;另外如果要得到预期的空kidsAges数组,要去掉list.add(10):
import java.util.ArrayList; import java.util.List; import org.junit.Test; public class UserInfo { @Test // JUnit测试方法不能是static,移除static修饰符 public String createUserWithFullJson() { List<Integer> list = new ArrayList<>(); // 若要输出空数组,注释掉此行 // list.add(10); RoomsInfo room = new RoomsInfo(2, list); List<RoomsInfo> roomsList = new ArrayList<>(); roomsList.add(room); Example ex = new Example("2023-06-01", "2023-06-02", roomsList, null, null, "Chalets%2B"); String UserJsonPayload = TestUtil.getSerializedJSON(ex); System.out.println(UserJsonPayload); return UserJsonPayload; } }
修复后的输出结果
{ "checkIn" : "2023-06-01", "checkOut" : "2023-06-02", "roomsInfo" : [ { "adultsCount" : 2, "kidsAges" : [] } ], "searchInfo" : null, "crossSellDetail" : null, "query" : "Chalets%2B" }
内容的提问来源于stack exchange,提问作者Saurav Singh Rawat
相关产品推荐
相关产品推荐

