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 |