In this blog, we will look at how to create web services starting from XSD. You will probably start with XSD, when you are using contract first development and defining contract for your web services or have an existing XSD that you would want to use as part of web service development. Lot’s of industry schemas is available as XSD such as ACORD and while developing industry solutions for interoperability, you would typically use XSD approach if a standard schema is available for that industry domain. XSD would provide the input and output message format for web service operations.
We will revisit the sample example of Order process application that I had listed in my blog – CXF and Spring Tutorial . In that blog, I had used the code first approach, where I started with Java code and exposed it as web services.
First we would create the contract for the Order Processing web service. We would name this as Order.xsd. Following shows the listing of Order.xsd. For simplicity, we would use the same Order.xsd schema for input and output operations.
<?xml version=”1.0″ encoding=”UTF-8″?>
<xs:schema attributeFormDefault=”qualified” elementFormDefault=”qualified”
targetNamespace=”http://order.demo/” xmlns:tns=”http://order.demo/”
xmlns:xs=”http://www.w3.org/2001/XMLSchema”>
<xs:complexType name=”order”>
<xs:sequence>
<xs:element minOccurs=”0″ type=”xs:string” />
<xs:element minOccurs=”0″ type=”xs:string” />
<xs:element minOccurs=”0″ type=”xs:double” />
<xs:element minOccurs=”0″ type=”xs:int” />
<xs:element minOccurs=”0″ type=”xs:string” />
</xs:sequence>
</xs:complexType>
</xs:schema>
Once you have created the contract, there are two alternatives that you have. First alternative is to create a WSDL and include the XSD as part of it and than use the CXF WSDL2Java to create a service implementation. Next approach is to generate Java objects from XSD and used the generated object for input and output operations while creating web services. In this later approach, you don’t need to create a WSDL and instead can start off with Java code and use the generated object as input and output parameter for service methods. We would go with the second approach.
Next we would generate the Java type objects for XML Schema using XMLBeans . XMLBeans is a technology for accessing XML by binding it to Java types. Before that, let’s create the project structure for our web service project. To get started, I have provided the project source code in a zip file. Download the project and unzip it any drive.
The schemas folder contains the Order.xsd and src contains the source code for web service project. The build.xml contained in cxfxsdfirst folder, is the ant build file for building and running the project. The build.xml requires CXF_HOME environment variable to be set to CXF distribution as it uses CXF and dependent library files from CXF_HOME\lib for building and running the code .
Next we would, generate the Java XML schema code for Order.xsd by running the following command.
ant buildOrderXMLBean
This buildOrderXMLBean uses the org.apache.xmlbeans.impl.tool.XMLBean class to generate Java types for Order.xsd. After running the above command, the generated compiled files would be packaged inside jar file named orderxmlbeans.jar and copied into build folder. The order element defined in Order.xsd would be mapped to the generated Order class. We would use the Order class as input and output parameter for the web service operation.
Next, we would create a service interface and service implementation for Order Process service. The service interface and implementation is exactly the same as Order Process service that was developed in code first approach in my earlier blog, hence I will no got into much details on explaining the code. If you need more details, please refer to my earlier post-CXF and Spring Tutorial
Following shows the service interface. The source code is available in cxfxsdfirst/src/demo/order
package demo.order;
import javax.jws.WebService;
@WebService
public interface OrderProcess {
Order processOrder(Order order);
}
Note that the Order class parameter comes from the generated Java types. That’s the only difference from code first approach in terms of service interface and implementation, where we have had created the Order java bean upfront.
The implementation class is OrderProcessImpl.java. Following shows the listing
package demo.order;
import javax.jws.WebService;
@WebService
public class OrderProcessImpl implements OrderProcess {
public Order processOrder(Order order) {
String orderID = validate(order);
order.setId(orderID);
return order;
}
//Rest of the code commented out. Refer to downloaded code
}
Next, we would create a Stand-alone server named Server.java that would publish the order process server. The following shows the code listing. The code is available in cxfxsdfirst/src/demo/order.
package demo.order;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.cxf.databinding.DataBinding;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
public class Server {
public static void main(String[] args) {
// Service instance
OrderProcess orderProcess = new OrderProcessImpl();
//AddressVerifyProcess orderProcess = new AddressVerifyProcessImpl();
JaxWsServerFactoryBean restServer = new JaxWsServerFactoryBean();
restServer.setServiceBean(orderProcess);
restServer.setAddress(“http://localhost:8080/”);
try {
restServer.setDataBinding(org.apache.cxf.xmlbeans.XmlBeansDataBinding.class.newInstance());
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (InstantiationException e1) {
e1.printStackTrace();
}
restServer.create();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
br.readLine();
} catch (IOException e) {
}
System.out.println(“Server Stopped”);
}
}
The code above uses the JaxWsServerFactoryBean for publishing the Order Process service class over address http://localhost:8080/. The most important code of the Order Process is the following line.
restServer.setDataBinding(org.apache.cxf.xmlbeans.XmlBeansDataBinding.class.newInstance());
This tells the CFX framework to uses XmlBeans data binding , instead of default JAXB data binding.
Next , we would create a stand-alone client that would invoke the Order Process service. The client and Spring configuration file s similar to one developed for code first. If you need details of the explanation of the code. please refer to Developing a client section in CXF and Spring Tutorial blog.
The client code is available in – cxfxsdfirst/src/demo/order/client folder. Following shows the code listing for Client.java
package demo.order.client;
import demo.order.OrderProcess;
import demo.order.Order;
import demo.order.impl.OrderImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Client {
public Client() {
}
public static void main(String args[]) throws Exception {
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext(new String[] {“demo/order/client/client-beans.xml”});
OrderProcess client = (OrderProcess) context.getBean(“orderClient”);
Order order = Order.Factory.newInstance();
order.setCustomerID(“C001”);
order.setItemID(“I001”);
order.setQty(100);
order.setPrice(200.00);
Order orderResponse = client.processOrder(order);
String message = (orderResponse.getId() == null) ? “Order not approved” : “Order approved; order ID is ” + orderResponse.getId();
System.out.println(message);
}
}
The following shows the client-beans.xml, the Spring configuration file which is used by Client.java.
<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:jaxws=”http://cxf.apache.org/jaxws”
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”>
<jaxws:client id=”orderClient” serviceClass=”demo.order.OrderProcess” address=”http://localhost:8080/orderapp/OrderProcess” >
<jaxws:dataBinding>
<bean/>
</jaxws:dataBinding>
</jaxws:client>
</beans>
The following definition tells the CXF framework to use XMLBeans data binding framework.
<jaxws:dataBinding>
<bean/>
</jaxws:dataBinding>
Next, we would see our code in action. The outline is same as one defined in Running the code section of my earlier blog “ CXF and Spring Tutorial
Navigate to cxfxsdfirst and type in the following command
- ant build
This would build the source code.
- ant server
This would execute the Java class – demo.order.Server and publish the OrderProcess service over address http://localhost:8080 .You can see the WSDL for OrderProcess service by typing the URL – http://localhost:8080/OrderProcess?wsdl in the browser
- ant client
Open up a new window and type the above command. The would execute the Java class – demo.order.client.Client and invoke the OrderProcess service. You would see the order id being displayed in the console.
To know, more about how to develop SOAP and RESTful web services, get a copy of my Apache CXF Web Service Book –