用于JSON处理的Java API(JSR-353)是用于生成和使用JSON的Java标准,它是Java EE 7的一部分引入。JSR-353包括对象(类似于DOM)和流(类似于StAX)API。 在本文中,我将演示我们在EclipseLink 2.6中添加到MOXy的JSON绑定中的最初JSR-353支持。 现在,您可以使用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)批注。
顾客
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;
}
}
电话号码
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提供程序 )
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
元帅演示
在下面的演示代码中,我们将结合使用JSR-353和MOXy API来生成JSON。 JSR-353的JsonObjectBuilder和JsonArrayBuilder用于生成JsonObject和JsonArray的实例。 通过将MOXy包装在MOXy的JsonObjectBuilderResult和JsonArrayBuilderResult实例中,我们可以使用MOXy封送这些构建器。
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();
}
}
输出量
以下是运行Marshal演示( MarshalDemo )的输出。 突出显示的部分(第2-12和18-25行)对应于从我们的Java模型填充的部分。
[
{
"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使您可以从JSR-353 JsonStructure ( JsonObject或JsonArray )解组。 要做到这一点只需换歼sonStructure在莫西的JsonStructureSource的实例,并使用需要来源的一个实例解组操作之一。
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输入将使用JsonReader转换为JsonArray。
[
{
"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 )的输出。
Jane
Bob
555-2222
555-3333