日期:2014-05-16  浏览次数:20398 次

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