2015-12-04 7 views
5

JSONからポリモーフィック型を非整列化するためにJacksonを使用しています。私はthis post@JsonTypeInfo,@JsonSubTypes、および@JsonTypeNameの注釈を例4と同様に使用しています。私の質問は、私のコードを拡張し、第3のクラスを追加する他の人が必要だと言うことです:public class Duck extends Animal元のコードベースの外に。どのようにしてpublic abstract Animal classのソースコード(注釈)を変更せずにSubType情報を追加することができますか?Javaでポリモーフィズムを使用して実行時にSubType情報を追加します。

UPDATE:

Iは、POJOのバージョン変更を解決するために@JsonTypeNameを使用するように強制しています。たとえば:

package my.zoo; 
@JsonTypeInfo( 
    use = JsonTypeInfo.Id.NAME, 
    include = JsonTypeInfo.As.PROPERTY, 
    property = "type") 
@JsonSubTypes({ 
    @Type(value = Cat.class, name = "[email protected]"), 
    @Type(value = Dog.class, name = "[email protected]"), 
    @Type(value = Catv2.class, name = "[email protected]")}) 
public abstract class Animal { 
    ... 
} 

@JsonTypeName("[email protected]") 
public class Cat extends Animal { 
    ... 
} 

@JsonTypeName("[email protected]") 
public class Catv2 extends Animal { 
    ... 
} 

@JsonTypeName("[email protected]") 
public class Dog extends Animal { 
    ... 
} 

// in another java package/project 
package another.zoo; 
import my.zoo.*; 

@JsonTypeName("[email protected]") 
public class Dogv2 extends Animal { 
    ... 
} 

は今、私が直面しています問題は、私はAnimalクラスに@Type(value = another.zoo.Dogv2.class, name = "[email protected]")})を追加することなく、名称「[email protected]」と入力しているJSONを非整列化することができないということです。したがって、アノテーションでこれを行うことは明らかに不可能です。実行時にこれを行う方法はありますか?

UPDATE 2:

私はちょうど同じ/類似したユースケースでthis SO questionを発見しました。私の心配は、アノテーションを使用すると、人々があなたの基本クラス/インタフェースを拡張/実装できないことです。私はまだ私の基本クラス/インターフェイスの拡張性を維持し、私の(un)マーシャリングロジックが将来の具体的な型で動作することを確認する方法が欲しいです。

答えて

3

Reflectionsライブラリを使用してAnimalクラスのすべてのサブタイプを見つけ出し、mapper.registerSubtypes(Class<?>... classes)メソッドで登録しました。

+0

@JsonTypeInfoアノテーションで何をしましたか? JsonTypeInfo.Id.NAMEを使用しましたか? – ampofila

+0

@ampofilaの場合、モデルコードはサンプルコードのとおりです。 。 RegisterSubtypes()呼び出しは、ブートストラップ時にアプリケーションドライバで行われました。ジャクソンをデシリアライズするとき、ジャクソンはすべてを世話します。 – derrdji

+0

迅速な対応に感謝します。しかし、私はどのようにRESTサービスをインターセプトするのか分かりません(私はインターフェイスとしてparamを取り、インバウンドjsonを自動的にunmarhsallsするコントローラを持っています)。あなたの方法は、ファイルから何かを読むときに機能しますが、RESTを使ったPOSTリクエストには適していません。 – ampofila

2

@JsonSubTypesを使用しないでください。シリアライズおよびデシリアライズのタイプを識別するには、@JsonTypeInfo#useJsonTypeInfo.Id.CLASSを使用します。

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type") 
abstract class Animal { /* whatever */ } 

ジャクソンは完全修飾名を格納してオブジェクトをシリアライズし、それを再度使用してデシリアライズの対象クラスを決定します。

サブクラスにはtypeという名前のプロパティがないことを確認する必要があります。


それは@JsonSubTypesで、この作品を作ることが可能だが、それはミックスインを伴い、非常に保守ソリューションではありません。

+0

チップをありがとう!しかし、私は、@JsonTypeName( "")アノテーションを更新された例のように使用することを余儀なくされています。それに取り組む方法はありますか? – derrdji

+0

@SotiriosDelimanolisはい、このようにしても、jsonテキスト(つまり、{"type": "my.class"、 "data":{...}})に完全なクラス名を渡す必要があります。右? – ampofila

+0

@ampofilaこの設定では、はい。他のオプションについては、['JsonTypeInfo.Id.Custom'](http://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonTypeInfo.Id.html#CUSTOM)があります。 –

関連する問題