关于fasterxml-jackson发生Can not deserialize instance of异常原因验证
这两天线上有大量的java.lang.IllegalArgumentException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: N/A; line: -1, column: -1]错误发生。
有经验的人一看,就知道是对象属性转换发生异常了。为了把这个错误的根本原因找到。只能上代码模拟了。
/**
* Created by changle on 17/1/9.
*/
@Slf4j
public class JSONTest {
public static void main(String[] args) {
testAtoB();
//testAtoB() 发生:Can not deserialize instance of com.test.JSONTest$Hobby out of START_ARRAY token
testBtoA();
//testBtoA() 发生:Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
}
public static void testAtoB(){
List<Hobby> hobbies = new ArrayList<>();
Random random = new Random();
for(int i=0;i<3;i++){
Hobby hobby = new Hobby(random.nextInt(),"测试名称","测试类型",random.nextInt(100));
hobbies.add(hobby);
}
StudentA studentA = new StudentA();
studentA.setAge(23);
studentA.setFromCity(true);
studentA.setMoney(3000);
studentA.setName("张三");
studentA.setHobbies(hobbies);
try {
String str = JSON.json(studentA);
log.info("str={}",str);
//list转换单个projo
StudentB studentB = JsonUtil.jsonObject(str, StudentB.class);
log.info("studentB.name:{}",studentB.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void testBtoA(){
Random random = new Random();
Hobby hobby = new Hobby(random.nextInt(), "测试名称", "测试类型", random.nextInt(100));
StudentB studentB2 = new StudentB();
studentB2.setAge(23);
studentB2.setFromCity(true);
studentB2.setMoney(3000);
studentB2.setName("张三");
studentB2.setHobbies(hobby);
String str2 = null;
try {
str2 = JSON.json(studentB2);
//单个projo转换list
StudentA studentA2 = JsonUtil.jsonObject(str2, StudentA.class);
log.info("studentB.name:{}", studentA2 == null ? "" : studentA2.getName());
} catch (IOException e) {
e.printStackTrace();
}
}
@Data
public static class StudentA{
private String name;
private int age;
private long money;
private boolean isFromCity;
private List<Hobby> hobbies;
}
@Data
public static class StudentB{
private String name;
private int age;
private long money;
private boolean isFromCity;
private Hobby hobbies;
}
@Data
public static class Hobby{
private long hId;
private String hName;
private String type;
private int score;
public Hobby(){}
public Hobby(long hId,String hName,String type,int score){
this.hId = hId;
this.hName = hName;
this.type = type;
this.score = score;
}
}
}
结论:
Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
该错误是因为目标类属性keyX需要ArrayList类型的,待转换的json串里属性名keyX对应的,不是一个ArrayList集合,而是单个
POJO。
Can not deserialize instance of com.test.JSONTest$Hobby out of START_ARRAY token
该错误是因为目标类属性keyX需要JSONTest$Hobby类型的,待转换的json串里属性名keyX对应的,不是一个POJO对象,而是ArrayList集合。