In my previous post I showed how to create RESTful services using Spring Framework. For representation of resources in XML I used JAXB and I followed the bottom-up approach (I wrote the Java classes and I let to generate XML/XSD from Java classes). In this post I will demonstrate how you can generate the same Java classes (User and UserList) from XML Schema (XSD) during Maven build, therefore using a top-down approach. For generation of Java classes from XML Schema during Maven build I will use Java.net Maven 2 JAXB 2 Plugin.
Along with the default generation of Java classes from XML Schema using xjc tool, I will add the following customizations:
- Making all the generated classes to implement
Serializable(useful when you want to use classes with some remote services: RMI, EJB, etc). - Use
java.util.Calendarinstead ofjavax.xml.datatype.XMLGregorianCalendarfor fields generated from elements of typexs:dateTime. - Generated classes should also have a generated
toString()method. - Classes have to be annotated with
XmlRootElement(required by Spring Framework when classes are used to represent state in RESTful services). - You can further enhance and customize the generation of Java classes using various plugins.
Project sources are available for download. So let’s start, step by step:
- Create Maven project. Below you can see the POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.zmeu</groupId> <artifactId>zmeu-blog-maven-jaxb</artifactId> <version>1.0-SNAPSHOT</version> <name>ZMEU Blog Maven JAXB</name> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <version>0.8.0</version> <configuration> <schemaDirectory>src/main/resources/schema</schemaDirectory> <bindingDirectory>src/main/resources/schema</bindingDirectory> <generatePackage>org.zmeu.blog.jaxb</generatePackage> <strict>false</strict> <extension>true</extension> <plugins> <plugin> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics</artifactId> <version>0.6.2</version> </plugin> <plugin> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics-annotate</artifactId> <version>0.6.2</version> </plugin> </plugins> <args> <arg>-Xannotate</arg> <arg>-XtoString</arg> </args> </configuration> <executions> <execution> <id>generate</id> <goals> <goal>generate</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics-runtime</artifactId> <version>0.6.2</version> </dependency> </dependencies> </project> - Write XML Schema (
schema.xsd):<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="user" type="user" /> <xs:element name="userList" type="userList" /> <xs:complexType name="user"> <xs:all> <xs:element name="id" type="xs:long" minOccurs="0" /> <xs:element name="name" type="xs:string" /> <xs:element name="registrationDate" type="xs:dateTime" /> </xs:all> </xs:complexType> <xs:complexType name="userList"> <xs:sequence> <xs:element name="user" type="user" minOccurs="0" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:schema> - Customize JAXB Bindings (
binding.xjb):<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:annox="http://annox.dev.java.net" xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd" version="2.1"> <jaxb:globalBindings> <!-- Use java.util.Calendar instead of javax.xml.datatype.XMLGregorianCalendar for xs:dateTime --> <jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime" /> <!-- Force all classes implements Serializable --> <xjc:serializable uid="1" /> </jaxb:globalBindings> <!-- Annotate the following classes with XmlRootElement --> <jaxb:bindings schemaLocation="schema.xsd" node="/xs:schema"> <jaxb:bindings node="xs:complexType[@name='user']"> <annox:annotate> <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="user" /> </annox:annotate> </jaxb:bindings> <jaxb:bindings node="xs:complexType[@name='userList']"> <annox:annotate> <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="userList" /> </annox:annotate> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings> - Run the build using
mvn clean installcommand. Build must be successful. Generated classes will be located intarget/generated-sources/xjcdirectory. Below is a snippet from generatedUserclass:..... @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "user", propOrder = {}) @XmlRootElement(name = "user") public class User implements Serializable, ToString { private final static long serialVersionUID = 1L; protected Long id; @XmlElement(required = true) protected String name; @XmlElement(required = true, type = String.class) @XmlJavaTypeAdapter(Adapter1 .class) @XmlSchemaType(name = "dateTime") protected Calendar registrationDate; ..... } - You are done!
0 comments:
Post a Comment