Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
EclipseLink/Examples/MOXy/Spring/JAXBMetadata
In order to use EclipseLink JAXB with the Spring Framework, you simply need a jaxb.properties
file and an eclipselink.jar
on the classpath. No other special configuration is required. This document will demonstrate how to configure Spring to use EclipseLink JAXB.
Configuration: applicationContext.xml
In Spring, beans are configured using the applicationContext.xml
file. The following XML file will be used to configure our beans:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="lazyInit" value="true"/> <property name="contextPath" value="example.gettingstarted"/> </bean> <bean id="xmlHelper" class="example.gettingstarted.XMLHelper"> <property name="metadataFile"><value>classpath:eclipselink-oxm.xml</value></property> <property name="marshaller" ref="jaxbMarshaller"/> </bean> </beans>
Two beans are being defined here:
- xmlHelper
- This is the class that will do all of the work, i.e. marshal and unmarshal
- We use the "metadataFile" property to indicate that we want Spring to inject the XML metadata file
eclipselink-oxm.xml
into thesetMetadataFile
method on our xmlHelper bean - We use the "marshaller" property to indicate that we want Spring to inject an instance of
org.springframework.oxm.jaxb.Jaxb2Marshaller
- jaxbMarshaller
- This is an instance of the
org.springframework.oxm.jaxb.Jaxb2Marshaller
class that will be injected into our xmlHelper bean - We use the "contextPath" property to indicate the location of the model classes,
jaxb.properties
, and anObjectFactory
class orjaxb.index
file - We use the "lazyInit" property set to "true" to allow us to pass in the properties object containing the XML metadata file before the underlying JAXBContext is created
- This is an instance of the
Following is the jaxb.properties
file that tells Spring to use EclipseLink JAXB:
javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory
Bootstrapping the Application
The standard Spring bean lookup method can be used to gain access to the xmlHelper
bean:
// initialize IoC Container ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // retrieve the XMLHelper instance from the Container XMLHelper xmlHelper = (XMLHelper) appContext.getBean("xmlHelper");
Example
Here is an example of EclipseLink JAXB used with the Spring Framework.
Requirements
- EclipseLink
- The latest version of EclipseLink can be found on the EclipseLink download page.
eclipselink.jar
must be on the classpath.
- The latest version of EclipseLink can be found on the EclipseLink download page.
- Spring Framework
- The latest version of the Spring Framework can be found on the Spring download page.
- The JAR files in the
dist
folder of your Spring install as well ascommons-logging.jar
found in/projects/spring-build/lib/ivy
must be on the classpath.
- Model Classes
- The following model classes make use of standard JAXB annotations as well as MOXy extensions:
Source/Config Files
This section contains the various source and configuration files for the example.
eclipselink-oxm.xml
Following is the XML metadata file that will be applied to the model classes:
<?xml version="1.0" encoding="US-ASCII"?> <xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" package-name="example.gettingstarted"> <java-types> <java-type name="Customer"> <xml-root-element/> <xml-type name="customer" prop-order="name address phoneNumbers" /> <java-attributes> <xml-element java-attribute="name" xml-path="personal-info/name/text()" /> <xml-element java-attribute="address" xml-path="contact-info/address" /> <xml-element java-attribute="phoneNumbers" xml-path="contact-info/phone-number" /> </java-attributes> </java-type> <java-type name="PhoneNumber"> <java-attributes> <xml-attribute java-attribute="type" /> <xml-value java-attribute="value" /> </java-attributes> </java-type> </java-types> </xml-bindings>
example.gettingstarted.XMLHelper.java
This is the class responsible for marshal/unmarshal operations:
package example.gettingstarted; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import org.springframework.core.io.Resource; import org.springframework.oxm.XmlMappingException; import org.springframework.oxm.jaxb.Jaxb2Marshaller; public class XMLHelper { private static String ECLIPSELINK_OXM_KEY = "eclipselink-oxm-xml"; private Map<String, Object> properties; private Jaxb2Marshaller marshaller; /** * Unmarshal a given source */ public Object load(Source source) throws XmlMappingException, IOException { return marshaller.unmarshal(source); } /** * Marshal a given Object to a Result */ public void save(Object obj, Result result) throws XmlMappingException, IOException { marshaller.marshal(obj, result); } /** * This method is used by Spring to inject the eclipselink-oxm.xml metadata * file to be applied to the model. */ public void setMetadataFile(Resource metadataFile) throws IOException { properties = new HashMap<String, Object>(); properties.put(ECLIPSELINK_OXM_KEY, new StreamSource(metadataFile.getInputStream())); } /** * This method is used by Spring to inject an instance of Jaxb2Marshaller */ public void setMarshaller(Jaxb2Marshaller marshaller) { this.marshaller = marshaller; this.marshaller.setJaxbContextProperties(properties); } }
This code demonstrates how the XMLHelper bean can be acquired and used to perform marshal/unmarshal operations on a Customer.
// initialize IoC Container ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // retrieve the XMLHelper instance from the Container xmlHelper = (XMLHelper) appContext.getBean("xmlHelper"); // load Customer Customer customer = (Customer) xmlHelper.load(new StreamSource(new FileInputStream("customer-out.xml"))); // update Customer PhoneNumber pn = new PhoneNumber(); pn.setType("Additional"); pn.setValue("613-123-1234"); customer.getPhoneNumbers().add(pn); // save Customer xmlHelper.save(customer, new StreamResult(new FileOutputStream("customer-out.xml")));
customer.xml
This is a sample instance document.
<?xml version="1.0" encoding="UTF-8"?> <customer> <personal-info> <name>Jane Doe</name> </personal-info> <contact-info> <address> <city>My Town</city> <street>123 Any Street</street> </address> <phone-number type="work">613-555-1111</phone-number> <phone-number type="cell">613-555-2222</phone-number> </contact-info> </customer>
jaxb.index
This is the jaxb.index
file used by the context to identify the classes it will be responsible for.
Customer Address PhoneNumber