EclipseLink Moxy对最新java api for json(JSR-353)的实现

最新的jave ee 7中,对JSON的解析实现使用的是JSR-353,其中,Eclipse旗下的EclipseLink开源项目向JAVE EE 7中贡献了不少力量,其中包括JPA 2.1 (JSR-338)的实现,另外一个贡献是本文向大家介绍的EclipseLink MOXy项目,它是JAVE EE 7中JAX-RS(REST标准)的一个默认的JSON Provider.
首先简单介绍下Eclipse旗下的EclipseLink开源项目,它主要用来实现快速将JAVA中的对象转化为各种类型的XML,该项目主要有如下的特性:

支持JAXB中最多的注解
同时支持XML和JSON
支持最新的JPA 2.1
对JPA-RS的增强支持

 MOXY有十分强大的将各类JAVA对象 序列化为XML以及XML反序列化为JAVA对象的能力。这在REST架构的应用中,MOXY可以用来实现JAX-RS标准中的各种转换,

下面选用一个例子大致讲解下,首先是一个jaxb声明的pojo,如下

@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;
}

}


PhoneNumber类如下:

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;
}

}


要使用moxy的话,要在model的相同目录下,放置jaxb.properties 文件,内容为:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

下面来看下如何对对象进行序列化为JSON,使用的是MOXy的 JsonObjectBuilderResult和JsonArrayBuilderResult.



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 {

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();

//创建 JsonArrayBuilder
JsonArrayBuilder customersArrayBuilder = Json.createArrayBuilder();


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);


JsonArrayBuilderResult result =
new JsonArrayBuilderResult(customersArrayBuilder);
marshaller.marshal(customer, result);


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);


JsonArrayBuilderResult arrayBuilderResult = new JsonArrayBuilderResult();
marshaller.marshal(phoneNumbers, arrayBuilderResult);

customersArrayBuilder
// 用JSR-353 APIs 额外添加数据
.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();
}

}


输出为:
[
{
"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"
}
]
}
]


然后来一个反序列化的例子:

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")) {

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());
}
}
}

}


输入的JSON:
[
{
"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"
}
]
}
]

输出结果:

Jane


2 Bob


3 555-2222


4 555-3333
同时可以参考偶的译文:
http://developer.51cto.com/art/201306/399778.htm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值