gpt4 book ai didi

java - JAXB 使用 ID 引用而不是包含来序列化 XML

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:29:49 24 4
gpt4 key购买 nike

在 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>

这里的问题是,相同的房屋被多次列出。现在我添加未注释的 XmlIDREFXmlID 注释,这将导致 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 过于冗长,但这个缺少信息。我如何创建(和解码)类似于以下内容的内容:

<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 网络服务:

@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;
}
}

提前致谢。

最佳答案

如果您尝试序列化为与您提供的最后一个 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;
}
}

还有其他方法可以实现这一点(例如,创建一个包装器对象,它具有人和房屋的集合属性等),但希望您能理解。

关于java - JAXB 使用 ID 引用而不是包含来序列化 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13499647/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com