使用Jackson对JSON数组中存放不同对象反序列化

132 阅读1分钟

最近项目中遇到一个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层可以正常接口 image.png