最近项目中遇到一个JSON反序列化问题,看似很简单,但是又不常见,本来以为很容易解决,结果找了很多方法才解决了,基本过程大概是这样的。
JSON数组中存放不同对象序列化过程
基本代码
基本代码比较简单,首页一个枚举类型表示动物类型,然后一个动物父类有一个动物类型字段,有两个子类,一个是Cat,一个是Dog,Cat有自己的字段catType,Dog有自己的字段dogType,然后使用Jackson反序列化得到一个JONS数组。
public enum AnimalTypeEnum {
DOG,
CAT;
}
@Data
public class Animal {
private AnimalTypeEnum type;
}
@Data
public class Cat extends Animal {
private String catType;
}
@Data
public class Dog extends Animal {
private String dogType;
}
@Data
public class AnimalVo {
private Integer size;
private List<Animal> animals;
}
测试序列化代码
List<Animal> animals=new ArrayList<>();
Cat cat=new Cat();
cat.setCatType("英短");
Dog dog=new Dog();
dog.setDogType("哈士奇");
animals.add(cat);
animals.add(dog);
AnimalVo animalVo=new AnimalVo();
animalVo.setSize(2);
animalVo.setAnimals(animals);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(animalVo);
System.out.println(json);
序列化后的JSON
{
"size": 2,
"animals": [
{
"type": "CAT",
"catType": "英短"
},
{
"type": "DOG",
"dogType": "哈士奇"
}
]
}
反序列化过程
基本要求Controller层能直接通过 @RequestBody接口前端参数
反序列化基本要求也很简单,就是前端传一个JSON数据,后端使用 @RequestBody List<Animal> animals,能接收到就好了。
@PostMapping("/add")
public ResponseEntity<AnimalVo> add(@RequestBody AnimalVo animalVo) {
log.info("{}", JsonUtils.toJson(animalVo));
return ResponseEntity.ok(animalVo);
}
对Animal Cat Dog类进行代码改造
@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "CAT"),
@JsonSubTypes.Type(value = Dog.class, name = "DOG")})
public class Animal {
@JsonIgnore
private AnimalTypeEnum type;
}
@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "type")
public class Cat extends Animal {
private String catType;
}
@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "type")
public class Dog extends Animal {
private String dogType;
}
测试过程
发送HTTP POST请求
POST http://127.0.0.1/add
Content-Type: application/json
{"size":2,"animals":[{"type":"CAT","catType":"英短"},{"type":"DOG","dogType":"哈士奇"}]}
Controller层可以正常接口