杰克逊筛选和多态性
我有一个抽象类车辆:杰克逊筛选和多态性
@JsonFilter('Vehicle_Filter')
public abstract class Vehicle {
private String brand;
private int nbOfWheels;
//Other attributes, constructor & methods
}
我有一个子类汽车延长车辆:
@JsonFilter('Car_Filter')
public class Car extends Vehicle {
private int nbOfDoors;
private boolean isElectric;
//Other attributes, constructor & methods
}
而且我有另一个孩子类自行车延伸车辆:
@JsonFilter('Bike_Filter')
public class Bike extends Vehicle {
private double tirePressure;
private boolean isAllTerrain;
//Other attributes, constructor & methods
}
比方说,我有一个类VehicleCollection代表车辆的名单我想在一个HTML页面中显示:
@JsonFilter('VehicleCollection_Filter')
public abstract class VehicleCollection {
private List<Vehicle> vehicles;
//Other attributes, constructor & methods
}
对于这一点,我会用杰克逊(连载从fasterXML)。 假设我只想显示每辆车的一些属性。我将使用一个FilterProvider接口。
问题是:当我想过滤车辆的属性时,我不想区分它是自行车还是汽车。重要的是,它是一辆车。我以为我可以拿出即过滤时:
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("VehicleCollection_Filter", SimpleBeanPropertyFilter.filterOutAllExcept("vehicles"))
.addFilter("Vehicle_Filter", SimpleBeanPropertyFilter.filterOutAllExcept("brand", "nbOfDoors", "isElectric"));
...但是调用作家时,将引发此错误:Could not find filter with id: 'Car_Filter'
。似乎杰克逊不想听到多态性...
有没有人有同样的问题?如果是,我可以提示如何克服它吗?如果不是,是否有一些文件或一些关于为什么杰克逊过滤器不能处理继承问题的隐含解释?
首先,您得到的错误是因为当Jackson序列化一个Car
实例时,它会在该类上看到一个@JsonFilter
注释,并期望通过过滤器提供程序找到具有给定id的过滤器。
的方式来解决:
- 添加
.setFailOnUnknownId(false);
将消除错误,但会被序列化的所有领域。 - 添加一个默认过滤器
.setDefaultFilter(filterOutAllExcept("brand", "nbOfDoors", "isElectric"))
将应用当"Bike_Filter"
和"Car_Filter"
找不到。这将获得所需的输出,但灵活性有限。您为每个过滤器提供程序获得1个默认过滤器,并为每个过滤器提供程序获得每个类1个过滤器例如,您不能使用3个过滤器对类进行注释,并在提供者中选择其中的一个。 -
改为使用
@JsonView
。与过滤器不同,视图本身支持(多个)继承,并且您可以为每个字段/ getter指定多于1个,这提供了极大的灵活性。例如为:abstract class Vehicle { @JsonView(Detail.Basic.class) private String brand; @JsonView(Detail.Standard.class) private int nbOfWheels; } class Car extends Vehicle { @JsonView(Detail.FullCar.class) private int nbOfDoors; // multiple views on a field @JsonView({Detail.Standard.class, Detail.Type.class}) private boolean electric; } class Bike extends Vehicle { @JsonView(Detail.FullBike.class) private int tirePressure; @JsonView({Detail.Standard.class, Detail.Type.class}) private boolean allTerrain; } class Detail { // marker interfaces never implemented interface Basic {} interface Type {} interface Standard extends Basic {} interface FullCar extends Basic {} interface FullBike extends Basic {} // 1 view can inherit from many interface Full extends FullCar, FullBike {} } ObjectMapper mapper = new ObjectMapper(); // only 1 view per writer ObjectWriter basicWriter = mapper.writerWithView(Detail.Basic.class); ObjectWriter standardWriter = mapper.writerWithView(Detail.Standard.class); ObjectWriter typeWriter = mapper.writerWithView(Detail.Type.class);
视图是也错误更不容易随着比赛的类型而不是串即如果您在视图名称中存在拼写错误,则IDE将突出显示它。用@JsonFilter
ID可以得到运行时错误。
我猜,术语“子类”在@JsonView
docs但不是在@JsonFilter
提到这样一个事实docs是很好的解释,你可以得到所观察到的行为。
我尝试了所有解决方案,并且所有解决方案都工作正常! 我喜欢使用视图的人,因为它是更多的OO,更多的Java;)而且,对于那些讨厌编写普通字符串的人来说,这真是一种解脱!谢谢 ! –
如果最重要的是,它是一辆车为什么你有'@JsonFilter('Car_Filter')'?和'@JsonFilter('Bike_Filter')'? – Oleg
因为在应用程序的其他部分,我需要单独显示汽车和自行车 –