1

MOXy を使用して、フロント エンド クライアント用に特別にフォーマットされた応答を生成し、特定の関係を簡単に判断できるようにしようとしています。これは少し不自然な例ですが、次のようなことをしようとしています…</p>

public class Person {
    private Integer id;

    private String name;

    private Address address;
}

public class Address {
    private String street;

    private String locality;

    private String state;

    private String zip;
}

public class PersonCollectionResponse {
    private Set<Person> people;

    public Set<Person> getPeople() {
        return this.people;
    }

    private int getCount() {
        return this.people.size();
    }
}

…そして、次のような結果になりたい…</p>

{
    "meta": {
        "count": 2
    },

    "people": [{
        "id": 1,
        "name": "Danny Parker",
        "contact": {
            "locality": "Zoo York",
            "state": "New York"
        },
    }, {
        "id": 2,
        "name": "Oscar the Grouch",
        "contact": {
            "locality": "San Francisco",
            "state": "California"
        }

    }],

    "mappings": [{
        "person": 1,
        "zip": 10014
    }, {
        "person": 2,
        "zip": 94102
    }]
}

「人」セットはさほど難しいものではありませんが、EclipseLink OXM メタデータを作成するときにマッピングを機能させる方法に行き詰まっています。マッピングを取得できるように、人々がリストされる方法を再定義する方法を探しています。

<xml-element java-attribute="people">
    <xml-element java-attribute="id" xml-path="@id" />
    <xml-element java-attribute="zip" xml-path="@zip" />
</xml-element>

今ではそれが可能かもしれません。そこで、人から生成した List> を返す PersonCollectionResponse に getMappings を作成しました。これは理想的ではありませんが、もっと悪いことがあります。しかし、それが書き出されると、マップ オブジェクトは次のような文字列になります...</p>

"mappings": ["{person: 1, zip: 10014}", "{person: 2, zip: 94102}"]

私の質問はこれらの 1 つだと思います…</p>

  1. 要素を 2 回目に表示する方法を教えてください。ただし、出力は異なります。
  2. マップを文字列として引用せずに出力するにはどうすればよいですか?

最悪のシナリオは、ジェネリック マップのセットを新しいクラス オブジェクトに作成し、それらにもスキーマを提供することですが、それは避けたいことです。

4

1 に答える 1

0

現在、MOXyでは、単一のインスタンスの表現をJSON(またはXML)ツリー内の複数の場所に分割することはできません。希望するサポートの種類について、拡張リクエストを入力してください。

以下に、JSONメッセージの一部をマッピングする方法を示します。

部分回答#1

以下では、モデルを次のJSONメッセージにマッピングする方法について説明します。

{
   "meta" : {
      "count" : 2
   },
   "people" : [ {
      "id" : 1,
      "name" : "Danny Parker",
      "contact" : {
         "locality" : "Zoo York",
         "state" : "New York"
      }
   }, {
      "id" : 2,
      "name" : "Oscar the Grouch",
      "contact" : {
         "locality" : "San Francisco",
         "state" : "California"
      }
   } ]
}

oxm.xml

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum11870107">
    <java-types>
        <java-type name="PersonCollectionResponse">
            <java-attributes>
                <xml-element java-attribute="count" xml-path="meta/count/text()"/>
            </java-attributes>
        </java-type>
        <java-type name="Person">
            <xml-type prop-order="id name address"/>
            <java-attributes>
                <xml-element java-attribute="address" name="contact"/>
            </java-attributes>
        </java-type>
        <java-type name="Address">
            <java-attributes>
                <xml-transient java-attribute="zip"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

部分回答#2

次に、モデルを次のJSONメッセージにマッピングする方法について説明します。

{
   "meta" : {
      "count" : 2
   },
   "mappings" : [ {
      "person" : 2,
      "zip" : "94102"
   }, {
      "person" : 1,
      "zip" : "10014"
   } ]
}

oxm.xml

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum11870107">
    <java-types>
        <java-type name="PersonCollectionResponse">
            <java-attributes>
                <xml-element java-attribute="count" xml-path="meta/count/text()"/>
                <xml-element java-attribute="people" name="mappings"/>
            </java-attributes>
        </java-type>
        <java-type name="Person">
            <xml-type prop-order="id address"/>
            <java-attributes>
                <xml-element java-attribute="id" name="person"/>
                <xml-transient java-attribute="name"/>
                <xml-element java-attribute="address" xml-path="."/>
            </java-attributes>
        </java-type>
        <java-type name="Address" xml-accessor-type="NONE">
            <java-attributes>
                <xml-element java-attribute="zip"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

デモコード

同じデモコードを両方の部分的なソリューションで使用できます。

package forum11870107;

import java.util.*;
import javax.xml.bind.*;

import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum11870107/oxm.xml");
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jc = JAXBContext.newInstance(new Class[] {PersonCollectionResponse.class}, properties);

        PersonCollectionResponse pcr = new PersonCollectionResponse();

        Person person1 = new Person();
        person1.setId(1);
        person1.setName("Danny Parker");
        pcr.getPeople().add(person1);
        Address address1 = new Address();
        address1.setLocality("Zoo York");
        address1.setState("New York");
        address1.setZip("10014");
        person1.setAddress(address1);

        Person person2 = new Person();
        person2.setId(2);
        person2.setName("Oscar the Grouch");
        pcr.getPeople().add(person2);
        Address address2 = new Address();
        address2.setLocality("San Francisco");
        address2.setState("California");
        address2.setZip("94102");
        person2.setAddress(address2);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(pcr, System.out);
    }

}

ドメインモデル

以下は、両方の部分的なソリューションに使用されたドメインモデルです。

PersonCollectionResponse

package forum11870107;

import java.util.*;

public class PersonCollectionResponse {
    private Set<Person> people = new HashSet<Person>();

    public Set<Person> getPeople() {
        return this.people;
    }

    public void setPeople(Set<Person> people) {
        this.people = people;
    }

    public int getCount() {
        return this.people.size();
    }

}

package forum11870107;

public class Person {
    private Integer id;

    private String name;

    private Address address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

}

住所

package forum11870107;

public class Address {

    private String street;
    private String locality;
    private String state;
    private String zip;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getLocality() {
        return locality;
    }

    public void setLocality(String locality) {
        this.locality = locality;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

}

jaxb.properties

MOXyをJAXBプロバイダーとして指定するには、jaxb.propertiesドメインモデルと同じパッケージで呼び出されるファイルに次のエントリを含める必要があります(http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-asを参照)。 -your.html

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
于 2012-08-13T15:12:40.273 に答える