
在现代web服务交互中,经常会遇到json数据结构中包含多种不同类型对象的情况,例如一个数组中既有基类对象,也有其子类对象。当尝试将这样的json数组反序列化为java中的基类列表时,jackson默认的行为可能无法正确处理子类特有的字段,从而抛出unrecognizedpropertyexception。本文将深入探讨如何利用jackson的强大功能,优雅地解决这一多态反序列化挑战。
假设我们有一个Car基类和一个Truck子类(继承自Car),Truck类额外包含maxLoad和clearance等字段。当JSON数组中同时包含Car和Truck类型的数据,并且我们尝试将其反序列化为List<Car>时,Jackson在处理Truck对象时会遇到maxLoad等字段,但Car类中并未定义这些字段。默认情况下,Jackson会认为这些是无法识别的属性,并抛出com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException。虽然将列表类型改为List<Truck>可以避免异常,但这会导致非Truck类型的对象无法被正确反序列化,且无法满足将所有对象统一存储在基类列表中的需求。
Jackson提供了强大的注解机制来处理多态性。为了实现将混合类型的JSON数组反序列化为基类列表,我们需要在基类上使用@JsonTypeInfo和@JsonSubTypes注解。
@JsonTypeInfo: 此注解用于指定多态类型信息的处理方式。
@JsonSubTypes: 此注解用于列出基类的所有已知子类型。
首先,定义Java类结构并添加Jackson注解:
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION, defaultImpl = Car.class)
@JsonSubTypes(@JsonSubTypes.Type(value = Truck.class))
public class Car {
private String make;
private String model;
private short year;
private String bodyStyle;
private String engineType;
private int horsepower;
// 构造函数
public Car() {}
public Car(String make, String model, short year, String bodyStyle, String engineType, int horsepower) {
this.make = make;
this.model = model;
this.year = year;
this.bodyStyle = bodyStyle;
this.engineType = engineType;
this.horsepower = horsepower;
}
// Getters and Setters
public String getMake() { return make; }
public void setMake(String make) { this.make = make; }
public String getModel() { return model; }
public void setModel(String model) { this.model = model; }
public short getYear() { return year; }
public void setYear(short year) { this.year = year; }
public String getBodyStyle() { return bodyStyle; }
public void setBodyStyle(String bodyStyle) { this.bodyStyle = bodyStyle; }
public String getEngineType() { return engineType; }
public void setEngineType(String engineType) { this.engineType = engineType; }
public int getHorsepower() { return horsepower; }
public void setHorsepower(int horsepower) { this.horsepower = horsepower; }
@Override
public String toString() {
return "Car{" +
"make='" + make + '\'' +
", model='" + model + '\'' +
", year=" + year +
", bodyStyle='" + bodyStyle + '\'' +
", engineType='" + engineType + '\'' +
", horsepower=" + horsepower +
'}';
}
}
public class Truck extends Car {
private double maxLoad;
private double clearance;
// 构造函数
public Truck() {}
public Truck(String make, String model, short year, String bodyStyle, String engineType, int horsepower, double maxLoad, double clearance) {
super(make, model, year, bodyStyle, engineType, horsepower);
this.maxLoad = maxLoad;
this.clearance = clearance;
}
// Getters and Setters
public double getMaxLoad() { return maxLoad; }
public void setMaxLoad(double maxLoad) { this.maxLoad = maxLoad; }
public double getClearance() { return clearance; }
public void setClearance(double clearance) { this.clearance = clearance; }
@Override
public String toString() {
return "Truck{" +
"make='" + getMake() + '\'' +
", model='" + getModel() + '\'' +
", year=" + getYear() +
", bodyStyle='" + getBodyStyle() + '\'' +
", engineType='" + getEngineType() + '\'' +
", horsepower=" + getHorsepower() +
", maxLoad=" + maxLoad +
", clearance=" + clearance +
'}';
}
}接下来是用于测试的JSON数据文件(cars.json):
[
{
"make": "Ford",
"model": "Focus",
"year": 2018,
"engineType": "T4",
"bodyStyle": "hatchback",
"horsepower": 225
},
{
"make": "Toyota",
"model": "Prius",
"year": 2021,
"engineType": "T4",
"bodyStyle": "hatchback",
"horsepower": 121
},
{
"make": "Toyota",
"model": "RAV4",
"year": 2020,
"engineType": "V6",
"bodyStyle": "SUV",
"horsepower": 230
},
{
"make": "Toyota",
"model": "Tacoma",
"year": 2021,
"engineType": "V6",
"bodyStyle": "pickup",
"horsepower": 278,
"maxLoad": 1050,
"clearance": 9.4
},
{
"make": "Ford",
"model": "T150",
"year": 2017,
"horsepower": 450,
"bodyStyle": "pickup",
"maxLoad": 2320,
"clearance": 8.4
}
]最后,反序列化和验证代码:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestDeserialization {
private static final ObjectMapper mapper = new ObjectMapper();
public static void main(String[] args) {
InputStream src = TestDeserialization以上就是使用Jackson实现JSON混合类型数组到基类列表的反序列化的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号