In contesto RestFul-Webservice (Jersey) Devo eseguire il marshalling/serializzazione di un oggetto grafico in XML e JSON. Per semplicità provo a spiegare il problema con 2-3 classi:XML serializzato JAXB con riferimenti ID anziché contenimento
Person.java
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {
private String name;
// @XmlIDREF
@XmlElement(name = "house")
@XmlElementWrapper(name = "houses")
private Collection<House> houses;
public Person() {}
public Person(String name, Collection<House> houses) {
this.name = name;
this.houses = houses;
}
}
House.java
@XmlAccessorType(XmlAccessType.FIELD)
public class House {
// @XmlID
public String name;
public String location;
public House() {}
public House(String name, String location) {
this.name = name;
this.location = location;
}
}
Ora, quando ho serializzare una persona, il XML sarà simile a questo:
<people>
<person>
<name>Edward</name>
<houses>
<house>
<name>MyAppartment</name>
<location>London</location>
</house>
<house>
<name>MySecondAppartment</name>
<location>London</location>
</house>
</houses>
</person>
<person>
<name>Thomas</name>
<houses>
<house>
<name>MyAppartment</name>
<location>London</location>
</house>
<house>
<name>MySecondAppartment</name>
<location>London</location>
</house>
</houses>
</person>
</people>
Il problema qui è che le stesse case sono elencate più volte. Ora aggiungo i decommentato XmlIDREF
e XmlID
annotazioni, il che porterebbe a XML simile a questo:
<people>
<person>
<name>Edward</name>
<houses>
<house>MyAppartment</house>
<house>MySecondAppartment</house>
</houses>
</person>
<person>
<name>Thomas</name>
<houses>
<house>MyAppartment</house>
<house>MySecondAppartment</house>
</houses>
</person>
</people>
Mentre il primo XML è stato troppo prolisso, questo manca di informazioni. Come posso creare (e unmarshalling) qualcosa di simile a:
<people>
<person>
<name>Edward</name>
<houses>
<house>MyAppartment</house>
<house>MySecondAppartment</house>
</houses>
</person>
<person>
<name>Thomas</name>
<houses>
<house>MyAppartment</house>
<house>MySecondAppartment</house>
</houses>
</person>
<houses>
<house>
<name>MyAppartment</name>
<location>London</location>
</house>
<house>
<name>MySecondAppartment</name>
<location>London</location>
</house>
</houses>
</people>
La soluzione deve essere generico perché non voglio scrivere lezioni extra per ogni nuovo elemento nel grafico oggetto.
Per completezza, ecco il webservice riposante:
@Path("rest/persons")
public class TestService {
@GET
@Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_JSON })
public Collection<Person> test() throws Exception {
Collection<Person> persons = new ArrayList<Person>();
Collection<House> houses = new HashSet<House>();
houses.add(new House("MyAppartment", "London"));
houses.add(new House("MySecondAppartment", "London"));
persons.add(new Person("Thomas", houses));
persons.add(new Person("Edward", houses));
return persons;
}
}
Grazie in anticipo.
possibile duplicato di [Can JAXB marshal per contenimento in un primo momento quindi marshal da @XmlIDREF per riferimenti successivi?] (Http://stackoverflow.com/questions/7587095/can-jaxb-marshal-by-containment-at-first -then-marshal-by-xmlidref-per-secondsen) –
Potrei scrivere un '' 'XmlAdapter''' che riconfigura un'istanza superficiale di una sottoclasse' '' Casa''' contenente tutti i valori o solo un riferimento all'originale esempio, sì.Ma ci sono molti svantaggi: (1) dovrei scrivere sottoclassi per ogni classe nel grafo degli oggetti, (2) Dovrei aggiungere tutti '' '@ XmlAttribute''s nel' '' marshal () '' 'and' '' unmarshal() '' 'metodi, e infine (3) non produrrà un XML contenente le case come figli del nodo radice. Ci sono molte cose che dovrei adottare quando si cambia il modello. E tutto ciò potrebbe essere fatto automaticamente poiché tutte le informazioni sono lì. – steffen