1

Map可変バーを持つクラス Foo があります。ただし、要件として、オブジェクトとして表現できる必要があります。

そのため、GenericXmlAdapter を使用して、instanceof チェックを行い、Map アダプターを呼び出します。MapAdapter は、Map を、Map の要素の単なるリストである MapElementList に変換します。

コードは必要に応じて失敗します。つまり、GenericXmlAdapter が呼び出され、MapElementList が返されます。

しかし、悪名高いクラス MapElementList も、そのスーパークラスもこのコンテキストエラーに認識されていません

部分的な前進: MapAdapter は、シリアル化する必要がある Foo またはその他のクラスで参照されていません。そのため、MapAdapter の @XmlSeeAlso は役に立ちません。他の場所に追加する必要があります。どこ?が質問です。GenericXmlAdapter に追加しても役に立ちません。

コードの簡単な実行

class Foo{
   private Object bar;

   @XmlJavaAdapter(GenericAdapter.class)
   @XmlElement(name="bar")
   public Object getBar(){
      return bar;
   }
}

次の GenericAdapter は、期待どおり Jackson によって呼び出されます

class GenericAdapter extends XmlAdapter<Object,Object>{
   public Object marshall(Object v){
      final XmlAdapter adapter = getAppropriateAdapter(v);
      return adapter.marshall(v);
   }

   public Object unmarshall(Object v){
      final XmlAdapter adapter = getAppropriateAdapter(v);
      return adapter.unmarshall(v);
   }

   public XmlAdapter getAppropriateAdater(Object v){
      if(v instanceof Map){
         return MapAdapter();
      }
   }
}

次の MapAdapter は、期待どおり GenericAdapter によって呼び出されています

@XmlSeeAlso({ MapElement.class, MapElementList.class })
class MapAdapter<K,V> extends XmlAdapter<MapElementList<K,V>, Map<K,V>>{
   public MapElementList<K,V> marshall(Map<K,V> map){
      return new MapElementList(map);
   }

   public Map<K,V> unmarshall(MapElementList list){
      ...
   }
}

次の MapElementList は Map のリスト表現です

class MapElementList<K,V>{
   @XmlAnyElement
   private ArrayList<MapElement<K,V> list;

   //Getters and setters
}

以下は最終的にMapElementです

class MapElement<K,V>{
   @XmlAnyElement
   private K key;

   @XmlAnyElement
   private V value;

   //Getters and setters WITHOUT any annotations
}
4

0 に答える 0