DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Exploring Hazelcast With Spring Boot
  • How to Consume REST Web Service (GET/POST) in Java 11 or Above
  • User-Friendly API Publishing and Testing With Retrofit
  • Simplifying Database Operations With HarperDB SDK for Java

Trending

  • Detection and Mitigation of Lateral Movement in Cloud Networks
  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • Secrets Sprawl and AI: Why Your Non-Human Identities Need Attention Before You Deploy That LLM
  • Can You Run a MariaDB Cluster on a $150 Kubernetes Lab? I Gave It a Shot
  1. DZone
  2. Coding
  3. Java
  4. You Should Use JAXB Generated Classes for RESTful Web Services

You Should Use JAXB Generated Classes for RESTful Web Services

Learn how to build RESTful web services in Spring that can utilize either JSON or XML.

By 
John Thompson user avatar
John Thompson
·
Aug. 10, 15 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
12.7K Views

Join the DZone community and get the full member experience.

Join For Free

I remember in the late 90s / early 2000 all the buzz in programming was about XML. All the ‘experts’ said you had to be using XML for data exchange. XML does have many benefits. But often when programming today, XML is looked as ‘old school’ or too restrictive. XML sure can be finicky to work with. Many developers when given a choice (including myself) will use JSON over XML. JSON is much more forgiving than XML is, which makes it simpler to work with.

While XML may be old school, it still can be good to use. Even when you’re doing JSON based Restful web services.

Restful Web Services in Spring

I’m not going to cover building Restful Web Services in Spring in this post. That’s a future topic. But when you’re using Spring MVC to develop Restful Web Services, you can set up a lot of flexibility. I typically design my web services so the client can use JSON or XML. The standards support this, and it’s fairly easy to do.

Many of the examples you will see on the internet will start with using JAXB annotated Java POJOs. This works, but I also feel this is a mistake. The ‘contract’ for your web services is now a Java class. Which may work for you, but it’s not portable. What if one of your clients is writing in PHP? A JAXB annotated Java class is useless to them.

XML Schema

XML Schema is a specification for describing XML documents. Think of it as strong typing for an XML document. You can specify the properties, if they can be null, their data types, if they can be a list, etc. The capabilities of XML schema is very robust.

A really cool feature of JAXB is you can generate JAXB annotated Java POJOs from a XML Schema document. And when you do this, you now have a portable contract for the data types of your web services. Your ‘contract’ is no longer tied to the Java programming language. You could give the XML schema to someone building a client for your web service in another programming language, like C# maybe, and they can use the XML Schema to generate code for the client.

XML Schema is a widely accepted standard that is not tied to a specific programming language. By using XML schema and providing it to your clients you make your Restful Web Service easier to consume. Your clients have a standardised specification of exactly what they need to send.

JAXB Generated Classes for Restful Web Services

In this post, I’m going to show you how to setup a Maven project to create a Jar file of Java classes generated by JAXB from an XML Schema.

Generating a Maven Project in IntelliJ

For the purposes of this example, I’m going to use IntelliJ to create a Maven project. In real use, you’ll want to set this up as either a independent Maven project, or a Maven module. This will allow the JAXB generated classes to be bundled in a JAR file and reused in other projects or modules.

1. Create a new project in IntelliJ.

Create Maven Project in IntelliJ


2. Set the GroupId and ArtifactId in the New Project dialog of IntelliJ.

New Project Dialog in IntelliJ


3. Select where to store the project on your drive.

path location in IntelliJ


4. IntelliJ will as your to verify the creation of a new directory. Click OK.

Directory Does Not Exist dialog in IntelliJ


5. Depending on your settings in IntelliJ, you may be asked to import changes. I often keep this feature off when dealing with large complex Maven projects due to performance reasons. If you see this dialog, click on ‘Import Changes’.

import Maven changes into IntelliJ

6. At this point you’ve created a new Maven project in IntelliJ. You can see the Maven standard directory structure has been created.

Maven project in IntelliJ

Create the XML Schema

The first file we will create is the XML Schema we will be using. Let’s say we’re creating a Web Service to add a product, and need a create product command object.

In our XML Schema we are creating a Product class, and the a CreateProductRequest class too. This is going to extend the ProductClass and add a field for the API key. This file is placed in the folder /main/resources. This is the default location for XML Schema files.
jaxb.xsd

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0">

    <!--This tells JAXB what package to create the Java classes in-->
    <xsd:annotation>
        <xsd:appinfo>
            <jaxb:schemaBindings>
                <jaxb:package name="guru.springframework.domain"/>
            </jaxb:schemaBindings>
        </xsd:appinfo>
    </xsd:annotation>

    <xsd:complexType name="Product">
        <xsd:sequence>
            <xsd:element name="productId" type="xsd:integer"/>
            <xsd:element name="productDescription" type="xsd:string"/>
            <xsd:element name="productPrice" type="xsd:decimal"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="CreateProductRequest">
        <xsd:complexContent>
            <xsd:extension base="Product">
                <xsd:attribute name="apikey" type="xsd:string"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

</xsd:schema>

Configure Maven

Creating the project in IntelliJ gave us a very basic Maven POM file. Here is the Maven POM created for us.

<?xml version="1.0" encoding="UTF-8"?>
<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>guru.springframework</groupId>
    <artifactId>jaxb-xsd-example</artifactId>
    <version>1.0-SNAPSHOT</version>

</project>

Maven Dependencies

We need to add three dependencies to our Maven POM. This first is the JAXB API, the second is the JAXB implementation, and finally the third is for the Maven JAXB plugin.

    <dependencies>
        <!--jaxb support-->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2.12</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.11</version>
        </dependency>
    </dependencies>

Maven JAXB Plugin

Next we need to configure the JAXB plugin for Maven to the Maven POM.

            <plugin>
                <groupId>org.jvnet.jaxb2.maven2</groupId>
                <artifactId>maven-jaxb2-plugin</artifactId>
                <version>0.12.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Complete Maven POM

Here is the final Maven POM.

<?xml version="1.0" encoding="UTF-8"?>
<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>guru.springframework</groupId>
    <artifactId>jaxb-xsd-example</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--jaxb support-->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2.12</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.11</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.jvnet.jaxb2.maven2</groupId>
                <artifactId>maven-jaxb2-plugin</artifactId>
                <version>0.12.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Building Our JAXB Maven Project

Running the Maven Package Goal

IntelliJ makes working with Maven very easy. On the right side of the IDE, you’ll see a button for ‘Maven Projects’, clicking that will open the ‘Maven Projects’ dialog. To build our project, under Lifecycle, double click on the ‘package’ goal.

Maven Projects in IntelliJ

You should see Maven run and build successfully.

[INFO] 
[INFO] --- maven-jar-plugin:2.3.2:jar (default-jar) @ jaxb-xsd-example ---
[INFO] Building jar: /Users/jt/src/springframework.guru/blog/jaxb-xsd-example/target/jaxb-xsd-example-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.410s
[INFO] Finished at: Fri Aug 07 07:23:44 EDT 2015
[INFO] Final Memory: 16M/207M
[INFO] ------------------------------------------------------------------------

Maven Build Artifacts

Maven will build into the ‘Target’ directory. You can see the Java classes generated in IntelliJ.

JAXB Maven Artifacts

JAXB Generated Classes

We expected two classes generated from the XML Schema we defined.

Product.java

// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2015.08.07 at 07:23:43 AM EDT 
//


package guru.springframework.domain;

import java.math.BigDecimal;
import java.math.BigInteger;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for Product complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="Product"&gt;
 *   &lt;complexContent&gt;
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *       &lt;sequence&gt;
 *         &lt;element name="productId" type="{http://www.w3.org/2001/XMLSchema}integer"/&gt;
 *         &lt;element name="productDescription" type="{http://www.w3.org/2001/XMLSchema}string"/&gt;
 *         &lt;element name="productPrice" type="{http://www.w3.org/2001/XMLSchema}decimal"/&gt;
 *       &lt;/sequence&gt;
 *     &lt;/restriction&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Product", propOrder = {
    "productId",
    "productDescription",
    "productPrice"
})
@XmlSeeAlso({
    CreateProductRequest.class
})
public class Product {

    @XmlElement(required = true)
    protected BigInteger productId;
    @XmlElement(required = true)
    protected String productDescription;
    @XmlElement(required = true)
    protected BigDecimal productPrice;

    /**
     * Gets the value of the productId property.
     * 
     * @return
     *     possible object is
     *     {@link BigInteger }
     *     
     */
    public BigInteger getProductId() {
        return productId;
    }

    /**
     * Sets the value of the productId property.
     * 
     * @param value
     *     allowed object is
     *     {@link BigInteger }
     *     
     */
    public void setProductId(BigInteger value) {
        this.productId = value;
    }

    /**
     * Gets the value of the productDescription property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getProductDescription() {
        return productDescription;
    }

    /**
     * Sets the value of the productDescription property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setProductDescription(String value) {
        this.productDescription = value;
    }

    /**
     * Gets the value of the productPrice property.
     * 
     * @return
     *     possible object is
     *     {@link BigDecimal }
     *     
     */
    public BigDecimal getProductPrice() {
        return productPrice;
    }

    /**
     * Sets the value of the productPrice property.
     * 
     * @param value
     *     allowed object is
     *     {@link BigDecimal }
     *     
     */
    public void setProductPrice(BigDecimal value) {
        this.productPrice = value;
    }

}

CreateProductRequest.java

Notice how this class actually extends the Product class.

// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2015.08.07 at 07:23:43 AM EDT 
//


package guru.springframework.domain;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for CreateProductRequest complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="CreateProductRequest"&gt;
 *   &lt;complexContent&gt;
 *     &lt;extension base="{}Product"&gt;
 *       &lt;attribute name="apikey" type="{http://www.w3.org/2001/XMLSchema}string" /&gt;
 *     &lt;/extension&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CreateProductRequest")
public class CreateProductRequest
    extends Product
{

    @XmlAttribute(name = "apikey")
    protected String apikey;

    /**
     * Gets the value of the apikey property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getApikey() {
        return apikey;
    }

    /**
     * Sets the value of the apikey property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setApikey(String value) {
        this.apikey = value;
    }

}

Conclusion

This is just a very simple example of generating classing from an XML Schema using JAXB and Maven. In this post, I’ve shown you step by step how to use an XML Schema and JAXB to generate Java classes. The generated classes are bundled into a JAR file, which is portable and can be shared with other Java projects.

As a Spring Source consultant, I was at a large company which built a number of Restful APIs. The team building the APIs did not use JAXB to generate classes from an XML Schema. Rather they built the JAXB classes by hand and could not offer their clients an XML Schema. As a consumer of their APIs, it was a time consuming process to configure and troubleshoot my data types.

I’ve also done consulting in organizations where the team did use XML Schemas for building their APIs. Having the XML Schema made writing the client code a snap.

Resources

JAXB

You can find the documentation for the JAXB project here.

JAXB Maven Plugin

I used the default settings for the JAXB Maven plugin. Additional options are available. Documentation for the JAXB Maven plugin is here.

Project Source Code

The source code used in this tutorial is available on Github here.

Web Service XML REST Web Protocols Apache Maven Schema intellij Java (programming language)

Published at DZone with permission of John Thompson, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Exploring Hazelcast With Spring Boot
  • How to Consume REST Web Service (GET/POST) in Java 11 or Above
  • User-Friendly API Publishing and Testing With Retrofit
  • Simplifying Database Operations With HarperDB SDK for Java

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!