Java JAXB使用ID引用而不是包含序列化XML
在RESTfulWebService(Jersey)上下文中,我需要将对象图封送/序列化为XML和JSON。为了简单起见,我尝试用2-3个类来解释这个问题: Person.java 现在,当我序列化一个人时,XML将如下所示:Java JAXB使用ID引用而不是包含序列化XML,java,jaxb,xml-serialization,jersey,Java,Jaxb,Xml Serialization,Jersey,在RESTfulWebService(Jersey)上下文中,我需要将对象图封送/序列化为XML和JSON。为了简单起见,我尝试用2-3个类来解释这个问题: Person.java 现在,当我序列化一个人时,XML将如下所示: <people> <person> <name>Edward</name> <houses> <house>
<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>
虽然第一个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>
爱德华
我的公寓
我的第二适应部
托马斯
我的公寓
我的第二适应部
我的公寓
伦敦
我的第二适应部
伦敦
解决方案应该是泛型的,因为我不想为对象图中的每个新元素编写额外的类
为了完整起见,下面是restful 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;
}
}
@Path(“休息/人”)
公共类测试服务{
@得到
@产生({MediaType.TEXT_XML,MediaType.APPLICATION_JSON})
公共集合测试()引发异常{
收款人=新的ArrayList();
Collection houses=新HashSet();
房屋。添加(新房屋(“我的公寓”、“伦敦”);
房屋。添加(新房屋(“MySecondapartment”、“London”);
新增(新人员(“托马斯”,房屋));
新增(新人员(“爱德华”,房屋));
返回人员;
}
}
提前感谢。如果您试图序列化为与您给出的上一个XML示例相匹配的格式,那么我相信您的对象图的结构不正确 如果要提供
Person
对象及其关联房屋的集合,并同时提供House
对象的集合,则需要返回包含这两个集合的序列化XML消息。看起来好像您的@XmlIDREF
和@XmlID
注释位于正确的位置,以便按照您的意愿(基于您的描述)建立人屋关联,但您只返回人屋
对象的集合,而不是返回两个集合
您的Web服务应该更像这样(省略序列化,因为您似乎清楚如何序列化它):
@Path(“休息/人”)
公共类测试服务{
@得到
@产生({MediaType.TEXT_XML,MediaType.APPLICATION_JSON})
公共映射测试()引发异常{
Map peopleandhouse=newhashmap();
收款人=新的ArrayList();
Collection houses=新HashSet();
房屋。添加(新房屋(“我的公寓”、“伦敦”);
房屋。添加(新房屋(“MySecondapartment”、“London”);
新增(新人员(“托马斯”,房屋));
新增(新人员(“爱德华”,房屋));
人和房子。把(“房子”,房子);
人和房子。放置(“人”,人);
归还居民和房屋;
}
}
还有其他方法可以实现这一点(例如,创建一个包装器对象,该对象具有人员和房屋的集合属性,等等)但希望您能理解。我可以编写一个
XmlAdapter
的可能副本,它重新运行包含所有值的子类House
的浅实例,或者只引用原始实例,是的。但也有许多缺点:(1)我必须为对象图中的每个类编写子类,(2)我必须在marshal()
和unmarshal()
方法中添加所有@xmltattribute
,最后(3)它不会生成包含作为根节点子节点的房屋的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>
<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;
}
}
@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;
}
}