简体   繁体   中英

Converting JSON to XML and vice versa using Jackson API and JAXB Annotations

I'm trying to write a code which can take either XML or JSON input and output JSON or XML respectively. Ie, if I give XML it should give back JSON, and if I give JSON it should give XML output.

I was told this is possible using Jackson API and JAXB Annotations. Can anyone help me out with this?

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

Below is an example of how you can use MOXy's JSON-binding to support this use case.

JAVA MODEL

Below is an example domain model annotated with JAXB metadata. The same metadata will be used for both the object-to-XML and object-to-JSON conversions.

Customer

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

    private int id;

    private String firstName;

    @XmlElement(nillable=true)
    private String lastName;

    private List<PhoneNumber> phoneNumbers;

}

PhoneNumber

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {

    @XmlAttribute
    private String type;

    @XmlValue
    private String number;

}

XML INPUT

Below is the XML input that we will use. Note how the xsi:nil attribute is used on the lastName element to indicate a null value. Also note how the phoneNumbers element has a type attribute.

<?xml version="1.0" encoding="UTF-8"?>
<customer>
   <id>123</id>
   <firstName>Jane</firstName>
   <lastName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
   <phoneNumbers type="work">555-1111</phoneNumbers>
</customer>

DEMO CODE

jaxb.properties

To specify MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html ):

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Demo

The following demo code will convert the XML to the domain model and then back to JSON.

import java.io.File;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum14734741/input.xml");
        Customer customer = (Customer) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
        marshaller.marshal(customer, System.out);
    }

}

JSON OUTPUT

Note how the null value for the lastName key is represented as proper JSON. Also note how the type key doesn't contain any special indicator corresponding to it being an XML attribute in the XML representation.

{
   "id" : 123,
   "firstName" : "Jane",
   "lastName" : null,
   "phoneNumbers" : [ {
      "type" : "work",
      "value" : "555-1111"
   } ]
}

Sure, but don't think of it as converting between XML and JSON -- this is pretty much the wrong thing to do, causing compatibility issues -- but that of converting Java Objects (POJOs) to/from JSON and XML. You can use one or two tools for this: one common combination is to use Jackson for JSON, and JAXB for XML, to use their respective strengths.

It is also possible to use a single tool; Blaise explained how JAXB implementations can help. Similarly, you can use Jackson for both: for XML part you need to use Jackson XML module . With Jackson, you can use Jackson's own annotations (prefered), or JAXB annotations for compatibility; both work for XML and JSON use cases.

Use of XML module with Jackson does not differ a lot from default JSON processing, except that you will need XmlMapper sub-class of ObjectMapper . If using this from JAX-RS (like Jersey), you can use Jackson JAX-RS XML provider .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM