2017-10-26 4 views
0

ジャクソンでエンティティ継承を使用してフィールドを埋め込む方法は?私は抽象クラスをextenting二つのクラスがある場合

public abstract class Vehicle { 
    private String model; 
} 

public class Car extends Vehicle { 
    private int seatingCapacity; 
    private double topSpeed; 
} 

public class Truck extends Vehicle { 
    private double payloadCapacity; 
} 

を私はジャクソン(春・ブート)を使用してJSONのデータをシリアル化したいと思います。デフォルトJSONによって は次のようになります。

[ 
    {"model": "vw", "type": "car", "seatingCapacity": 5, ...}, 
    {"model": "volvo", "type": "truck", "payloadCapacity": 10, ...}, 
    ... 
] 

しかし、APIのため、私は、各サブクラスのための特定のフィールドは、クラス型の中に含めることがあることが必要です。

[ 
    { 
    "model": "vw", 
    "type": "car", 
    "car": {"seatingCapacity": 5, ...} 
    }, 
    { 
    "model": "volvo", 
    "type": "truck", 
    "truck": {"payloadCapacity": 10, ...} 
    }, 
    ... 
] 
+0

回避策は、サブクラスでfiedがそれぞれのパスで 'JsonProperty' @を追加することです。何かのように: '@JsonProperty(value =" car.seatingCapacity ")'。しかし、それは "car"の代わりに "car.seatingCapacity"キーを生成します:{"seatingCapacity":n} – user2813807

答えて

0

デフォルトのJSONは実際にあなたが定義した通りに車両を表すため、これは奇妙なケースです。私は、これらのオブジェクトは以下のようなものにクラスを変更するために送信された応答を表現するためだけに使用されている場合、最も簡単な方法は次のようになり言う:

public class Car extends Vehicle { 
    CarProperties car=new CarProperties(); 

    class CarProperties { 
     private int seatingCapacity; 
     private double topSpeed; 
    } 
} 

これは見て非常にクールではないかもしれませんが、それはあなたにJSONを表します欲しいです。また、Vehicleクラスにコードがなくてもプロパティを定義するだけの場合は、getModel()メソッドを1つ使用してインターフェイスに置き換えることもできます。

カスタムジャクソンシリアライザを作成することもできますが、コードをはるかに複雑にしてオブジェクトを結合します。もちろん、いくつかのJsonObjectクラスを使ってこれらのプロパティから独自のjsonを生成し、プロパティを手動で追加することもできます。

0

ジャクソンでは、必要に応じてカスタムデシリアライザを作成することができます。トラックや車と同じ構造を作る可能性があるなら、最初に実装する方が簡単です。しかし、そうでない場合は、あなたのようなものを作成することができます。

public class VehicleDeserializer extends JsonDeserializer<Vehicle> { 

    @Override 
    public Vehicle deserialize(JsonParser jp, DeserializationContext ctxt) 
     throws IOException, JsonProcessingException { 
     JsonNode node = jp.getCodec().readTree(jp); 

     String vehicleType = node.get("type").asText(); 

     if (vehicleType.equals("car")) { 
      // Values should be loaded through node 
      return new Car(); 
     } 

     if (vehicleType.equals("truck")) { 
      // Values should be loaded through node 
      return new Truck(); 
     } 

     // Return default or exception if not recognized 
    } 
} 

そしてObjectMapperを更新する必要があります。

ObjectMapper mapper = new ObjectMapper(); 
SimpleModule module = new SimpleModule(); 
module.addDeserializer(Vehicle.class, new VehicleDeserializer()); 
mapper.registerModule(module); 
関連する問題