2012-01-03 16 views
4

LinkedHashMap<String, Object>に拡張されたモデルクラスがいくつかあります。マップのgetメソッドとputメソッドをラップするgetterとsetterを定義しています。私はこれらのクラスのインスタンスを直列化しようとしていますが、JacksonはRESTEasyを使用していますが、Jacksonはget300に注意を払うことを拒否します。代わりに、バッキング・マップのキーと値のペアをシリアル化するだけです。私は@JsonAutoDetectを使って、すべてのメソッドとフィールドの自動検出を無効にしようとしましたが、何も変更されませんでした。 JacksonがMapを自動的にシリアル化しないようにする方法はありますか、またはLinkedHashMap<String, Object>を拡張しない新しいモデルクラスを作成する必要がありますか?Jackson - シリアライズ時にマップスーパークラスを無視する

答えて

7

私はLinkedHashMap<String, Object>を拡張し、いくつかのモデルクラスを持っている:あなた:彼らはこれがない継承を使用する際の典型的な例ですラップ地図のgetゲッターとセッターを定義し、メソッドに

を置きます他のコード(Jacksonなど)があなたのクラスをスーパークラスのインスタンスのように扱っていることがわかりました。これはあなたがしたいことではありません。これらのような場合(一般的に)、通常は継承よりも構成を使用するほうがよいでしょう。

にモデルクラスを書き換え、マップを拡張するのではなくにすることをお勧めします。あなたは道よりはるかに多くの制御を得て、結果として得られるモデルは脆弱ではありません。モデルをMapとして表示する必要がある場合は、そのビューをレンダリングするasMapメソッド(または同様のもの)を実装します。

+1

ご回答ありがとうございます。私は実際、コンポジションベースのアプローチに移行することを検討していました。 'LinkedHashMap'は実際に私のモデルクラスの直接スーパークラスではありません。代わりに、MongoDBの 'BasicDBObject'を拡張して、簡単に永続化させることができます。しかし、私はあまりにも多くの目的のためにこれらのオブジェクトを使用しようとしている可能性があります。 toDBObject()メソッドとfromDBObject()メソッドを追加するとうまくいくはずです。しかし、Jacksonがデフォルトの 'Map'シリアル化をやってしまうのを防ぐ方法があるかどうかは、まだ不思議です。特定のタイプのシリアライザを無効にする方法はありますか? – gilby

9

@ skaffmanの回答に同意します。しかし、簡単に継承構造を変えることができない場合は、これを回避する方法があるかもしれません。

一つの可能​​性は、あなたがゲッター/セッターを定義するインターフェイスを持っているならば、あなたはジャクソンを強制する

@JsonSerialize(as=MyInterface.class) 
@JsonDeserialize(as=MyInterface.class) 

は、特定のインターフェイスを介して利用可能であるものを使用して追加することができますということです。

カスタムシリアライザ/デシリアライザも可能ですが、それはかなりの作業です。

2

あなたはジャクソンのorg.codehaus.jackson.map.deser.StdDeserializerProviderを拡張し、独自のorg.codehaus.jackson.map.DeserializerProviderを実装し、上書きすることができます方法_createDeserializer

import org.codehaus.jackson.map.SerializerProvider; 
import org.codehaus.jackson.map.deser.StdDeserializerProvider; 
import org.codehaus.jackson.map.DeserializationConfig; 
... 

class MyDeserializerProvider extends StdDeserializerProvider { 

    @Override 
    protected JsonDeserializer<Object> _createDeserializer(DeserializationConfig config, JavaType type, BeanProperty property) throws JsonMappingException { 
     if (type.isMapLikeType()) {  // (1) 
      return this._factory.createBeanDeserializer(config, this, type, property); 
     } else { 
      return super._createDeserializer(config, type, property); 
     } 
    } 
} 

(1)を使用している場合は、条件のカスタムデシリアライザはObjectMapperで直接登録されている

ニーズを満たしています:

ObjectMapper om = new ObjectMapper(); 
om.setDeserializerProvider(new MyDeserializerProvider()); 

これをジャクソン1.9.11でテストしました。

関連する問題