In a previous post I introduced how MOXy's Object Graph feature allows you to input and output partial models. In that example I demonstrated how to define a partial model via metadata. In this example we will create the object graphs programmatically. This gives you additional flexibility when you need to create one on the fly.
You can try this out today by downloading an EclipseLink 2.5.0 nightly download starting on March 24, 2013 from:
You can try this out today by downloading an EclipseLink 2.5.0 nightly download starting on March 24, 2013 from:
Java Model
Below is the Java model that we will use for this example. The model represents customer data. We will use an object graph to output just enough information so that someone could contact the customer by phone. In this example we won't specify the object graphs as part of the mapping metadata.
Customer
package blog.objectgraphs.runtime; import java.util.List; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Customer { @XmlAttribute private int id; private String name; private Address billingAddress; private Address shippingAddress; @XmlElementWrapper @XmlElement(name="phoneNumber") private List<PhoneNumber> phoneNumbers; }
Address
package blog.objectgraphs.runtime; import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class Address { private String street; private String city; private String province; private String postalCode; }
PhoneNumber
package blog.objectgraphs.runtime; import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class PhoneNumber { @XmlAttribute private String type; @XmlValue private String value; }
Demo Code
Demo
Demo
In the demo code below we will read in an XML document to fully populate our Java model. After marshalling it out to prove that everything was fully mapped we will create an object graph (lines 25-30). For properties that correspond to domain objects we can create subgraphs (lines 27 & 29) to filter their values. To be applied an object graph must be specified on the marshaler (line 33). Finally we output the subset to both XML and JSON.
package blog.objectgraphs.runtime; import java.io.File; import javax.xml.bind.*; import org.eclipse.persistence.jaxb.JAXBHelper; import org.eclipse.persistence.jaxb.MarshallerProperties; import org.eclipse.persistence.jaxb.ObjectGraph; import org.eclipse.persistence.jaxb.Subgraph; 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/blog/objectgraphs/runtime/input.xml"); Customer customer = (Customer) unmarshaller.unmarshal(xml); // Output XML Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(customer, System.out); // Create the Object Graph ObjectGraph contactInfo = JAXBHelper.getJAXBContext(jc).createObjectGraph(Customer.class); contactInfo.addAttributeNodes("name"); Subgraph location = contactInfo.addSubgraph("billingAddress"); location.addAttributeNodes("city", "province"); Subgraph simple = contactInfo.addSubgraph("phoneNumbers"); simple.addAttributeNodes("value"); // Output XML - Based on Object Graph marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, contactInfo); marshaller.marshal(customer, System.out); // Output JSON - Based on Object Graph marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json"); marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false); marshaller.setProperty(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true); marshaller.marshal(customer, System.out); } }
input.xml/Output
We will use the following document to populate our domain model. We will also marshal it back out to demonstrate that all of the content is actually mapped.
<?xml version="1.0" encoding="UTF-8"?> <customer id="123"> <name>Jane Doe</name> <billingAddress> <street>1 A Street</street> <city>Any Town</city> <province>Ontario</province> <postalCode>A1B 2C3</postalCode> </billingAddress> <shippingAddress> <street>2 B Road</street> <city>Another Place</city> <province>Quebec</province> <postalCode>X7Y 8Z9</postalCode> </shippingAddress> <phoneNumbers> <phoneNumber type="work">555-1111</phoneNumber> <phoneNumber type="home">555-2222</phoneNumber> </phoneNumbers> </customer>
XML Output Based on Object Graph
<?xml version="1.0" encoding="UTF-8"?> <customer> <name>Jane Doe</name> <billingAddress> <city>Any Town</city> <province>Ontario</province> </billingAddress> <phoneNumbers> <phoneNumber>555-1111</phoneNumber> <phoneNumber>555-2222</phoneNumber> </phoneNumbers> </customer>
JSON Output Based on Object Graph
Below is the same subset as the previous XML document represented as JSON. We have used the new JSON_WRAPPER_AS_ARRAY_NAME property (see Binding to JSON & XML - Handling Collections) to improve the representation of collection values.
{ "name" : "Jane Doe", "billingAddress" : { "city" : "Any Town", "province" : "Ontario" }, "phoneNumbers" : [ "555-1111", "555-2222" ] }
Further Reading
If you enjoyed this post then you may also be interested in:
- MOXy's Object Graphs - Input/Output Partial Models to XML & JSON
- Specifying EclipseLink MOXy as Your JAXB Provider
- JSON Binding with EclipseLink MOXy - Twitter Example
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.