2013-12-13 22 views
5

Ho un problema nel far sì che Moxy generi "buoni" XML e JSON per un elenco di oggetti ereditati. Uno o l'altro aspetto dell'XML o il JSON sembra soddisfacente, ma non allo stesso tempo. Ecco il modello:Moxy: elenco di oggetti XML e JSON non riescono ad avere entrambi l'aspetto

public static abstract class Animal { 
    private String name; 

    protected Animal() { 
    } 
    protected Animal(String name) { 
     this.name = name; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
} 
@XmlRootElement 
public static class Tiger extends Animal { 
    public Tiger() { 
    } 
    public Tiger(String name) { 
     super(name); 
    } 
} 

@XmlRootElement 
public static class Lion extends Animal { 
    public Lion() { 
    } 
    public Lion(String name) { 
     super(name); 
    } 
} 

@XmlRootElement 
public static class Zoo { 
    private List<Animal> animals = new ArrayList<>(); 

    @XmlElementRef 
    public List<Animal> getAnimals() { 
     return animals; 
    } 
    public void setAnimals(List<Animal> animals) { 
     this.animals = animals; 
    } 
    public void addAnimal(Animal a) { 
     animals.add(a); 
    } 
} 

L'XML e JSON generato dal seguente esempio Zoo

zoo = new Zoo(); 
    zoo.addAnimal(new Tiger("Hobbes")); 
    zoo.addAnimal(new Lion("Simba")); 
    zoo.addAnimal(new Tiger("Sherikan")); 

assomigliare:

<?xml version="1.0" encoding="UTF-8"?> 
    <zoo> 
    <tiger> 
     <name>Hobbes</name> 
    </tiger> 
    <lion> 
     <name>Simba</name> 
    </lion> 
    <tiger> 
     <name>Sherikan</name> 
    </tiger> 
    </zoo> 
    { 
    "zoo" : { 
     "tiger" : [ { 
      "name" : "Hobbes" 
     }, { 
      "name" : "Sherikan" 
     } ], 
     "lion" : [ { 
      "name" : "Simba" 
     } ] 
    } 
    } 

L'XML sembra esattamente quello che voglio anch'io, ma il JSON è strano. Il modo in cui il Moxy utilizza il tipo come chiave non conserva l'ordine tra gli elementi nell'elenco. È un bug o una funzionalità?

Se cambio l'annotazione sul Zoo.animals al @XmlElement l'uscita JSON guarda bene, ma l'output XML è cambiato a qualcosa che non posso usare.

{ 
    "zoo" : { 
     "animals" : [ { 
      "type" : "tiger", 
      "name" : "Hobbes" 
     }, { 
      "type" : "lion", 
      "name" : "Simba" 
     }, { 
      "type" : "tiger", 
      "name" : "Sherikan" 
     } ] 
    } 
    } 
    <?xml version="1.0" encoding="UTF-8"?> 
    <zoo> 
    <animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="tiger"> 
     <name>Hobbes</name> 
    </animals> 
    <animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="lion"> 
     <name>Simba</name> 
    </animals> 
    <animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="tiger"> 
     <name>Sherikan</name> 
    </animals> 
    </zoo> 

L'unico modo che è venuta in mente per risolvere questo è quello di creare un file di collegamento esterna OXM di ignorare l'annotazione sul Zoo.animals. L'associazione sottostante viene registrata utilizzando la proprietà di JAXBContextProperties.OXM_METADATA_SOURCE.

<?xml version="1.0"?> 
    <xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xml-accessor-type="PUBLIC_MEMBER" xml-accessor-order="ALPHABETICAL" 
       xml-mapping-metadata-complete="false" 
       package-name="com.example"> 
    <java-types> 
     <java-type name="com.example.JAXBTest2$Zoo"> 
      <java-attributes> 
       <xml-element java-attribute="animals"/> 
      </java-attributes> 
     </java-type> 
    </java-types> 
    </xml-bindings> 

C'è una soluzione migliore a questo che non utilizza un file di bind esterno?

risposta

2

Nota: Sono in vantaggio EclipseLink JAXB (MOXy) e un membro del gruppo di esperti JAXB (JSR-222)

Il modo in cui il Moxy utilizza il tipo di chiave non mantenere l'ordine tra gli elementi della lista. È un bug o una funzionalità?

Lo abbiamo fatto apposta per impedire che la chiave venga ripetuta.

L'unico modo che è venuta in mente per risolvere questo è quello di creare un file di collegamento esterna OXM di ignorare l'annotazione sul Zoo.animals. L'associazione di seguito viene registrata utilizzando la proprietà di JAXBContextProperties.OXM_METADATA_SOURCE.

Questo è il modo in cui consiglierei di risolvere il caso d'uso.

+0

Blaise, grazie per la tua rapida risposta. Conoscete il motivo della memorizzazione delle informazioni sul tipo nelle chiavi JSON invece di una proprietà di tipo sintetico nell'oggetto reale? – user3099799