I have an object graph that I would like to convert to and from JSON and XML, for the purposes of creating a REST-style API. It strikes me that someone must have done this already, but a quick search using Google and Stack Overflow reveals nothing.
Does anyone know of a suitable (Apache or equivalent license preferred) library to do this?
GSON from google : http://code.google.com/p/google-gson/,
or
Jackson the library used in spring :https://github.com/FasterXML/jackson
and I would concur with others suggesting jaxb for XML to pojo, well supported lots of tools : its the standard.
For POJO to XML I suggest using JAXB (there are other libraries as well, such as XStream for example, but JAXB is standardized).
For JSON I don't know anything, but if you want to implement a RESTful API, you might be interested in JSR-311 which defines a server-side API for RESTful APIs and Jersey, which is its reference implementation.
Use Xstream http://x-stream.github.io/ for xml and JSON http://www.json.org/java/ for JSON. I dont think there is one library that does both.
Or write a wrapper which delegates to XStream renderers/JSON renderers depending on what you want.
I think you may be looking for something similar to what is here: JSON.org Java section
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
EclipseLink JAXB (MOXy) supports mapping a single object model to both XML and JSON with the same metadata:
- http://blog.bdoughan.com/2011/08/binding-to-json-xml-geocode-example.html
License Information
- http://wiki.eclipse.org/EclipseLink/FAQ/General#How_is_EclipseLink_Licensed.3F
DOMAIN MODEL
Below is the domain model we will use for this example. For this example I'm just using the standard JAXB (JSR-222) annotations which have are available in the JDK/JRE since Java SE 6.
Customer
package forum658936;
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
String firstName;
@XmlElement(nillable=true)
String lastName;
@XmlElement(name="phone-number")
List<PhoneNumber> phoneNumbers;
}
PhoneNumber
package forum658936;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {
@XmlAttribute
int id;
@XmlValue
String number;
}
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
XML
input.xml
This is the XML that our demo code will read in and convert to domain objects.
<?xml version="1.0" encoding="UTF-8"?>
<customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<firstName>Jane</firstName>
<lastName xsi:nil="true"/>
<phone-number id="123">555-1234</phone-number>
</customer>
Things to note about the XML:
- The
xsi:nil
attribute is used to indicate that the lastName
is null.
- The
phone-number
element is a complex type with simple content (see: http://blog.bdoughan.com/2011/06/jaxb-and-complex-types-with-simple.html).
JSON
Output
Below is the JSON that was output by running the demo code.
{
"firstName" : "Jane",
"lastName" : null,
"phone-number" : [ {
"id" : 123,
"value" : "555-1234"
} ]
}
Things to note about the JSON:
- The
null
value is used to represent that the lastName
is null. There is no presence of the xsi:nil
attribute.
- The collect of phone numbers is of size 1 and is correctly bound by square brackets. Many libraries incorrectly treat collections of size 1 as JSON objects.
- The
property
of type int
was correctly marshalled without quotes.
- In the XML representation
id
was an attribute, but in the JSON representation there is not need for it to be specially represented.
DEMO CODE
In the demo code below we will convert an XML document to objects, and then convert those same instances to JSON.
Demo
MOXy doesn't just interpret JAXB annotations it is a JAXB implementation so the standard JAXB runtime APIs are used. JSON binding is enabled by specifying MOXy specify properties on the Marshaller
.
package forum658936;
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/forum658936/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-lib is licensed under the Apache 2.0 license.
It can also transform JSON objects to XML, but you'd need to convert your POJOs to JSON through it first.
Personally I would tackle the two separately; and to convert JSON<->XML via JSON<-> Pojo <-> XML.
With that: Java<->POJO with JAXB (http://jaxb.dev.java.net; also bundled with JDK 1.6) with annotations (XStream is ok too); and for JSON, Jackson's ObjectMapper (http://jackson.codehaus.org/Tutorial). Works nicely with Jersey, and I am use it myself (current Jersey version does not bundle full Pojo data binding by default, but will in near future)
I would actually not use any of xml libs to produce "json": XStream and JAXB/Jettison can produce kind of JSON, but it uses ugly conventions that are rather non-intuitive.
EDIT (18-Jul-2011): Jackson actually has an extension called "jackson-xml-databind" that can read/write XML, similar to JAXB. So it can be used for both JSON and XML, to/from POJOs.
Last I saw on the website, XStream will do both. It supports XML and JSON as serialization targets.
There are almost literally hundreds. My favorites are GSON for POJO <-> JSON and castor-xml for POJO <-> XML.
As a bonus both are licensed under Apache License 2.0 style licenses.
Have a look at Genson library http://code.google.com/p/genson/wiki/GettingStarted.
It is easy to use, performant and was designed with extension in mind.
Actually it does json/java conversion but not xml. However xml support may be added in a future version.
I'm using it in web applications and REST web services in jersey, but also in some cases to store objects in their json form into a database.
Ah and it's under Apache 2.0 license.