Java API для обработки JSON (JSR-353) — это стандарт Java для производства и использования JSON, который был представлен как часть Java EE 7. JSR-353 включает объектный (DOM-подобный) и потоковый (StAX-подобный) API. В этом посте я продемонстрирую первоначальную поддержку JSR-353, которую мы добавили к привязке JSON MOXy в EclipseLink 2.6. Теперь вы можете использовать MOXy для того, чтобы:
- javax.json.JsonArrayBuilder
 - javax.json.JsonObjectBuilder
 
И демаршал из:
- javax.json.JsonStructure
 - javax.json.JsonObject
 - javax.json.JsonArray
 
Вы можете попробовать это сегодня, используя ночную сборку EclipseLink 2.6.0:
Справочная реализация JSR-353 доступна здесь:
Модель Java
Ниже приведена простая модель клиента, которую мы будем использовать для этого поста. Обратите внимание, что для этого примера мы используем только стандартные аннотации JAXB (JSR-222) .
Клиент
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
 | 
package blog.jsonp.moxy;import java.util.*;import javax.xml.bind.annotation.*;@XmlType(propOrder={"id", "firstName", "lastName", "phoneNumbers"})public class Customer {    private int id;    private String firstName;    private String lastName;    private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getFirstName() {        return firstName;    }    public void setFirstName(String firstName) {        this.firstName = firstName;    }    @XmlElement(nillable=true)    public String getLastName() {        return lastName;    }    public void setLastName(String lastName) {        this.lastName = lastName;    }    @XmlElement    public List<PhoneNumber> getPhoneNumbers() {        return phoneNumbers;    }} | 
Номер телефона
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
 | 
package blog.jsonp.moxy;import javax.xml.bind.annotation.*;@XmlAccessorType(XmlAccessType.FIELD)public class PhoneNumber {    private String type;    private String number;    public String getType() {        return type;    }    public void setType(String type) {        this.type = type;    }    public String getNumber() {        return number;    }    public void setNumber(String number) {        this.number = number;    }} | 
jaxb.properties
Чтобы указать MOXy в качестве вашего JAXB-провайдера, вам нужно включить файл с именем jaxb.properties в тот же пакет, что и модель вашего домена, со следующей записью (см. Определение EclipseLink MOXy в качестве вашего JAXB-провайдера )
| 
 1 
 | 
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory | 
Маршал Демо
В демонстрационном коде ниже мы будем использовать комбинацию API-интерфейсов JSR-353 и MOXy для создания JSON. JsonObjectBuilder и JsonArrayBuilder в JSR-353 используются для создания экземпляров JsonObject и JsonArray . Мы можем использовать MOXy для маршалинга этих компоновщиков, оборачивая их в экземпляры JsonObjectBuilderResult и JsonArrayBuilderResult в MOXy .
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
 | 
package blog.jsonp.moxy;import java.util.*;import javax.json.*;import javax.json.stream.JsonGenerator;import javax.xml.bind.*;import org.eclipse.persistence.jaxb.JAXBContextProperties;import org.eclipse.persistence.oxm.json.*;public class MarshalDemo {    public static void main(String[] args) throws Exception {        // Create the EclipseLink JAXB (MOXy) Marshaller        Map<String, Object> jaxbProperties = new HashMap<String, Object>(2);        jaxbProperties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");        jaxbProperties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);        JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class},             jaxbProperties);        Marshaller marshaller = jc.createMarshaller();        // Create the JsonArrayBuilder        JsonArrayBuilder customersArrayBuilder = Json.createArrayBuilder();        // Build the First Customer        Customer customer = new Customer();        customer.setId(1);        customer.setFirstName("Jane");        customer.setLastName(null);        PhoneNumber phoneNumber = new PhoneNumber();        phoneNumber.setType("cell");        phoneNumber.setNumber("555-1111");        customer.getPhoneNumbers().add(phoneNumber);        // Marshal the First Customer Object into the JsonArray        JsonArrayBuilderResult result =             new JsonArrayBuilderResult(customersArrayBuilder);        marshaller.marshal(customer, result);        // Build List of PhoneNumer Objects for Second Customer        List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>(2);        PhoneNumber workPhone = new PhoneNumber();        workPhone.setType("work");        workPhone.setNumber("555-2222");        phoneNumbers.add(workPhone);        PhoneNumber homePhone = new PhoneNumber();        homePhone.setType("home");        homePhone.setNumber("555-3333");        phoneNumbers.add(homePhone);        // Marshal the List of PhoneNumber Objects        JsonArrayBuilderResult arrayBuilderResult = new JsonArrayBuilderResult();        marshaller.marshal(phoneNumbers, arrayBuilderResult);        customersArrayBuilder            // Use JSR-353 APIs for Second Customer's Data            .add(Json.createObjectBuilder()                .add("id", 2)                .add("firstName", "Bob")                .addNull("lastName")                // Included Marshalled PhoneNumber Objects                .add("phoneNumbers", arrayBuilderResult.getJsonArrayBuilder())             )        .build();        // Write JSON to System.out        Map<String, Object> jsonProperties = new HashMap<String, Object>(1);        jsonProperties.put(JsonGenerator.PRETTY_PRINTING, true);        JsonWriterFactory writerFactory = Json.createWriterFactory(jsonProperties);        JsonWriter writer = writerFactory.createWriter(System.out);        writer.writeArray(customersArrayBuilder.build());        writer.close();    }} | 
Выход
Ниже приведен результат запуска демоверсии маршала ( MarshalDemo ). Выделенные части (строки 2-12 и 18-25) соответствуют частям, которые были заполнены из нашей модели Java.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
 | 
[    {        "id":1,        "firstName":"Jane",        "lastName":null,        "phoneNumbers":[            {                "type":"cell",                "number":"555-1111"            }        ]    },    {        "id":2,        "firstName":"Bob",        "lastName":null,        "phoneNumbers":[            {                "type":"work",                "number":"555-2222"            },            {                "type":"home",                "number":"555-3333"            }        ]    }] | 
Демарш Демо
MOXy позволяет отменять маршализацию из JsonStructure JSR-353 ( JsonObject или JsonArray ). Для этого просто оберните J sonStructure в экземпляр JsonStructureSource в MOXy и используйте одну из операций демаршала, которая использует экземпляр Source .
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
 | 
package blog.jsonp.moxy;import java.io.FileInputStream;import java.util.*;import javax.json.*;import javax.xml.bind.*;import org.eclipse.persistence.jaxb.JAXBContextProperties;import org.eclipse.persistence.oxm.json.JsonStructureSource;public class UnmarshalDemo {    public static void main(String[] args) throws Exception {        try (FileInputStream is = new FileInputStream("src/blog/jsonp/moxy/input.json")) {            // Create the EclipseLink JAXB (MOXy) Unmarshaller            Map<String, Object> jaxbProperties = new HashMap<String, Object>(2);            jaxbProperties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");            jaxbProperties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);            JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class},                 jaxbProperties);            Unmarshaller unmarshaller = jc.createUnmarshaller();            // Parse the JSON            JsonReader jsonReader = Json.createReader(is);            // Unmarshal Root Level JsonArray            JsonArray customersArray = jsonReader.readArray();            JsonStructureSource arraySource = new JsonStructureSource(customersArray);            List<Customer> customers =                 (List<Customer>) unmarshaller.unmarshal(arraySource, Customer.class)                .getValue();            for(Customer customer : customers) {                System.out.println(customer.getFirstName());            }            // Unmarshal Nested JsonObject            JsonObject customerObject = customersArray.getJsonObject(1);            JsonStructureSource objectSource = new JsonStructureSource(customerObject);            Customer customer = unmarshaller.unmarshal(objectSource, Customer.class)                .getValue();            for(PhoneNumber phoneNumber : customer.getPhoneNumbers()) {                System.out.println(phoneNumber.getNumber());            }        }    }} | 
Ввод (input.json)
Следующий вход JSON будет преобразован в JsonArray с помощью JsonReader .
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
 | 
[    {        "id":1,        "firstName":"Jane",        "lastName":null,        "phoneNumbers":[            {                "type":"cell",                "number":"555-1111"            }        ]    },    {        "id":2,        "firstName":"Bob",        "lastName":null,        "phoneNumbers":[            {                "type":"work",                "number":"555-2222"            },            {                "type":"home",                "number":"555-3333"            }        ]    }] | 
Выход
Ниже приведен результат запуска демаршал демо ( UnmarshalDemo ).
| 
 1 
2 
3 
4 
 | 
JaneBob555-2222555-3333 |