ste*_*fen 6 java jaxb jersey xml-serialization
在RestFul-Webservice(Jersey)上下文中,我需要将Object图形编组/序列化为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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当我序列化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>
Run Code Online (Sandbox Code Playgroud)
这里的问题是,相同的房屋被多次列出.现在我添加了未注释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>
Run Code Online (Sandbox Code Playgroud)
虽然第一个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>
Run Code Online (Sandbox Code Playgroud)
解决方案应该是通用的,因为我不想为对象图中的每个新元素编写额外的类.
为了完整性,这里是宁静的web服务:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.
如果您尝试序列化为与您给出的最后一个 XML 示例相匹配的格式,那么我相信您的对象图的结构不正确,无法实现这一目标。
如果您想要提供Person对象的集合及其关联的房屋,并且还提供对象的集合House,那么您需要返回包含这两个集合的序列化 XML 消息。看起来好像您的@XmlIDREF和@XmlID注释位于正确的位置,以便按照您的意图(根据您的描述)建立人-房屋关联,但您只返回对象的集合,Person而不是返回两个集合。
您的网络服务应该看起来更像这样(省略序列化,因为您似乎很清楚如何序列化它):
@Path("rest/persons")
public class TestService {
@GET
@Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_JSON })
public Map<String, Object> test() throws Exception {
Map<String, Object> peopleAndHouses = new HashMap<String, Object>();
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));
peopleAndHouses.put("houses", houses);
peopleAndHouses.put("people", persons);
return peopleAndHouses;
}
}
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以实现此目的(例如,创建一个包装对象,该对象具有人员和房屋等的集合属性),但希望您能明白这一点。