【发布时间】:2012-11-10 01:56:48
【问题描述】:
在 RestFul-Webservice (Jersey) 上下文中,我需要将对象图编组/序列化为 XML 和 JSON。为简单起见,我尝试用 2-3 个类来解释问题:
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;
}
}
现在当我序列化一个 Person 时,XML 将如下所示:
<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>
这里的问题是,相同的房屋被多次列出。现在我添加未注释的 XmlIDREF 和 XmlID 注释,这将导致 XML 类似于:
<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>
虽然第一个 XML 过于冗长,但这个 XML 缺乏信息。如何创建(和解组)类似于:
<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>
解决方案应该是通用的,因为我不想为对象图中的每个新元素编写额外的类。
为了完整起见,这里是宁静的网络服务:
@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;
}
}
提前致谢。
【问题讨论】:
-
我可以编写一个
XmlAdapter来返回包含所有值的子类House的浅实例,或者只引用原始实例,是的。但是有很多缺点:(1)我必须为对象图中的每个类编写子类,(2)我必须在marshal()和unmarshal()方法中添加所有@XmlAttributes,以及最后 (3) 它不会生成包含作为根节点子节点的房屋的 XML。更改模型时,我必须采用许多事情。所有这些都可以自动完成,因为所有信息都在那里。
标签: java jaxb xml-serialization jersey