Java JAXB使用ID引用而不是包含序列化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>

在RESTfulWebService(Jersey)上下文中,我需要将对象图封送/序列化为XML和JSON。为了简单起见,我尝试用2-3个类来解释这个问题:

Person.java

现在,当我序列化一个人时,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>
虽然第一个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;
    }
}