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
|
Jane Bob 555-2222 555-3333 |