W kontekście RestFul-Webservice (Jersey) potrzebuję przygotować/uszeregować wykres Object do XML i JSON. Dla uproszczenia staram się wyjaśnić problem z 2-3 klas:Serializowany XML JAXB z odniesieniami ID, a nie ograniczeniami
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;
}
}
Teraz kiedy serializacji danej osoby XML będzie wyglądał następująco:
<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>
Problem polega na tym, że te same domy są wymienione wiele razy. Teraz dodam odkomentowane XmlIDREF
i XmlID
adnotacje, co powodowałoby XML podobny do tego:
<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>
ile pierwszy był zbyt gadatliwy XML, ten brak informacji. Jak mogę stworzyć (i unmarshal) coś podobnego do:
<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>
Roztwór powinien mieć charakter ogólny, ponieważ nie chcę pisać dodatkowe zajęcia dla każdego nowego elementu wykresu obiektu.
Dla kompletności, tutaj jest spokojny usługa:
@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;
}
}
góry dzięki.
prawdopodobny duplikat [Czy JAXB marszałek przez powstrzymanie na początku następnie marszałek przez @XmlIDREF dla kolejnych odniesień?] (Http://stackoverflow.com/questions/7587095/can-jaxb-marshal-by-containment-at-first -then-marshal-by-xmlidref-for-subshen) –
Mógłbym napisać '' 'XmlAdapter''', który poprawia płytkie wystąpienie podklasy" '' 'House''' zawierającej wszystkie wartości lub tylko odniesienie do oryginału przykład, tak.Ale jest wiele wad: (1) Musiałbym napisać podklasy dla każdej klasy na wykresie obiektu, (2) Musiałbym dodać wszystkie '' '@ XmlAttribute''' w' '' marshal () '' i '' 'unmarshal()' '' metody, a na końcu (3) nie będzie produkować XML zawierających domy jako dzieci węzła głównego. Jest wiele rzeczy, którymi musiałbym się zająć przy zmianie modelu. A wszystko to można zrobić automatycznie, ponieważ wszystkie informacje tam są. – steffen