2017-10-21 93 views
1

我有一個抽象類車輛傑克遜篩選和多態性

@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'。似乎傑克遜不想聽到多態性...

有沒有人有同樣的問題?如果是,我可以提示如何克服它嗎?如果不是,是否有一些文件或一些關於爲什麼傑克遜過濾器不能處理繼承問題的隱含解釋?

+0

如果最重要的是,它是一輛車爲什麼你有'@JsonFilter('Car_Filter')'?和'@JsonFilter('Bike_Filter')'? – Oleg

+0

因爲在應用程序的其他部分,我需要單獨顯示汽車和自行車 –

回答

0

首先,您得到的錯誤是因爲當Jackson序列化一個Car實例時,它會在該類上看到一個@JsonFilter註釋,並期望通過過濾器提供程序找到具有給定id的過濾器。

的方式來解決:

  1. 添加.setFailOnUnknownId(false);將消除錯誤,但會被序列化的所有領域。
  2. 添加一個默認過濾器.setDefaultFilter(filterOutAllExcept("brand", "nbOfDoors", "isElectric"))將應用當"Bike_Filter""Car_Filter"找不到。這將獲得所需的輸出,但靈活性有限。您爲每個過濾器提供程序獲得1個默認過濾器,併爲每個過濾器提供程序獲得每個類1個過濾器例如,您不能使用3個過濾器對類進行註釋,並在提供者中選擇其中的一個。
  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可以得到運行時錯誤。

我猜,術語「子類」@JsonViewdocs但不是在@JsonFilter提到這樣一個事實docs是很好的解釋,你可以得到所觀察到的行爲。

+0

我嘗試了所有解決方案,並且所有解決方案都工作正常! 我喜歡使用視圖的人,因爲它是更多的OO,更多的Java;)而且,對於那些討厭編寫普通字符串的人來說,這真是一種解脫!謝謝 ! –