6

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>

オブジェクトグラフの新しい要素ごとに追加のクラスを記述したくないので、ソリューションは一般的なものにする必要があります。

完全を期すために、ここに安らかな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;
    }
}

前もって感謝します。

4

1 に答える 1

2

最後に提供した XML の例と一致する形式にシリアル化しようとしている場合は、オブジェクト グラフが正しく構成されていないと思います。

オブジェクトのコレクションPersonとそれに関連付けられた家を提供し、Houseオブジェクトのコレクションも提供する場合は、両方のコレクションを含むシリアル化された XML メッセージを返す必要があります。(説明に基づいて) 意図したとおりに Person-House 関連付けを作成するための正しい場所に注釈があるように見えますが、両方のコレクションを返すのではなく、オブジェクトのコレクションのみ@XmlIDREFを返します。@XmlIDPerson

Web サービスは次のようになります (シリアル化の方法は明らかであるため、シリアル化は省略します)。

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

これを実現する方法は他にもあります (たとえば、人や家のコレクション属性を持つラッパー オブジェクトを作成するなど)。

于 2013-01-08T13:25:38.947 に答える