Using custom datatypes with JAXB

In this demo, we will create two classes (Customer and Address), to be returned from our service method. These classes themselves are not web services, but represent the data to be serialized using XML. Since the xml to representing this info is auto generated, at times, more control on the structure of the XML.

We use JAXB annotations to control this. Some of these are..

These annotations allow us to define the elements, datatypes, attributes, namespaces, etc.

Address.java

package com.vinod.model;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlType(name = "addressType", namespace = "http://kvinod.com/types")
public class Address {
	private String city, state;

	public Address() {
	}

	@XmlElement(name = "city")
	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	@XmlElement(name = "state")
	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

}

The Customer class acts as a container for the Address class

Customer.java

package com.vinod.model;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlType (name="customerType", namespace="http://kvinod.com/types")
@XmlRootElement(name = "customer")
public class Customer {
	private String name;
	private Address address;

	public Customer() {
	}

	@XmlElement(name = "customer-name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@XmlElement(name = "customer-address")
	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

}

CustomerService.java

package com.vinod.service;

import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;

import com.vinod.model.Address;
import com.vinod.model.Customer;

@WebService(name = "ICustomerService", portName = "CustomerServicePort", 
		serviceName = "CustomerService", targetNamespace = "http://kvinod.com/services")
public class CustomerService {

	@WebMethod(operationName = "getCustomerData", action = "getCustomerData")
	@WebResult(name="customer")
	public Customer getCustomer() {
		// dummy method to return a customer
		Customer cust = new Customer();
		cust.setName("Vinod");
		cust.setAddress(new Address());
		cust.getAddress().setCity("Bangalore");
		cust.getAddress().setState("Karnataka");
		return cust;
	}
}

and finally, the web service publisher

CustomerServicePublisher.java

package com.vinod.utils;

import javax.xml.ws.Endpoint;

import com.vinod.service.CustomerService;

public class CustomerServicePublisher {
	public static void main(String[] args) {
		CustomerService service=new CustomerService();
		String url="http://localhost:9999/customerService";
		Endpoint.publish(url, service);
		System.out.printf("Customer service published at %s\n", url);
	}
}

Check the WSDL published at the url http://localhost:9999/customerService?WSDL and follow the schema definition defined within the <types /> tag.

Here is how it looks:

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:tns="http://kvinod.com/types" 
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	version="1.0" targetNamespace="http://kvinod.com/types">

	<xs:complexType name="customerType">
		<xs:sequence>
			<xs:element name="customer-address" 
				type="tns:addressType"
				minOccurs="0" />
				
			<xs:element name="customer-name" 
				type="xs:string"
				minOccurs="0" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="addressType">
		<xs:sequence>
			<xs:element name="city" 
				type="xs:string" minOccurs="0" />
				
			<xs:element name="state" 
				type="xs:string" minOccurs="0" />
		</xs:sequence>
	</xs:complexType>
</xs:schema>

Observe the names of the elements and types. These are the ones specified in the annotations

To test this, I am using the free soap tool called SoapUI. You can download this from http://soapui.org. Once, downloaded and installed, create a new SoapUI project.

New SoapUI project

In the "Initial WSDL/WADL: " box, copy and paste the WSDL location from the browser.

New SoapUI project data

This will scan through the WSDL and creates a tree structure displaying the operations available in the WSDL, and creates one request for each.

SoapUI request

Double click the Request node from the tree, and you will be opening and editor populated with the XML SOAP request. If there are parameters to be supplied, then question mark (?) will be shown, which you must replace with the value of the parameter. In this example, there is none. Just click the green colored arrow on the top left corner to make a request and in a second, you will get the SOAP response from the server.

SOAP request/response
  1. You can start from here - Hello Web Service
  2. Using custom classes and JAXB annotations


Use the following links to navigate