2017-10-21 12 views
1

私は抽象クラス持っている:私は車を拡張カー 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 
} 

そして、私は持っていますもう1つの子クラス自転車車延長:

@JsonFilter('Bike_Filter') 
public class Bike extends Vehicle { 
    private double tirePressure; 
    private boolean isAllTerrain; 
    //Other attributes, constructor & methods 
} 
01私はfasterXMLからジャクソンを(使用して、それをシリアル化します、そのために

@JsonFilter('VehicleCollection_Filter') 
public abstract class VehicleCollection { 
    private List<Vehicle> vehicles; 
    //Other attributes, constructor & methods 
} 

のは、私はHTMLページに表示したいと思う車のリストを表すクラスVehicleCollectionを持っているとしましょう)。 各車両の一部の属性のみを表示したいとします。 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

まず、ジャクソンがCarインスタンスをシリアル化すると、クラスに@JsonFilterアノテーションがあり、指定されたIDを持つフィルタがフィルタプロバイダから見つかることが予想されるためです。

解決する方法:

  1. をエラーを排除するが、すべてのフィールドをシリアル化する原因となります.setFailOnUnknownId(false);を追加します。
  2. "Bike_Filter""Car_Filter"が見つからない場合に適用されるデフォルトのフィルタ.setDefaultFilter(filterOutAllExcept("brand", "nbOfDoors", "isElectric"))を追加します。これにより、必要な出力が得られますが、柔軟性は制限されます。すべてのフィルタプロバイダに対して、フィルタプロバイダごとのすべてのクラスに対して1つのデフォルトフィルタを、クラスごとに1つのフィルタを取得します。 3つのフィルタでクラスに注釈を付けることはできません。たとえば、プロバイダでそれらのフィルタの1つを選択することはできません。
  3. 代わりに@JsonViewを使用してください。フィルタとは異なり、ビュー自体は(複数の)継承をサポートしており、フィールド/ゲッターごとに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ではなく@JsonFilterdocsに記載されているという事実は、あなたが観察された行動のために得ることができるように良い説明です。推測します

+0

すべてのソリューションを試しましたが、それらのすべてが機能します。 私はビューを使用しているものに優先度を持っていますが、これはもっと多くのオブジェクト指向、もっとJavaです;)また、プレーンなストリングの作成を嫌う人にとっては、本当に安心です!どうも ! –

関連する問題