This is an ongoing blog to Web Services development. In my previous blog, I talked about JAX-WS framework in detail and how to create code first web services. In this blog, I would describe how to create Contract first web services.
Contract First Web Service
With Contract First approach for web services development, you start off with defining the XML Schema/WSDL contract for your service instead of Java code. One you have defined a WS- Compatible WSDL, you can take any programming language like Java or .Net for its implementation.
Note : For Contract First Web service development , you must be have a good idea about XML , XML Schema and WSDL specification.
As you have already analyzed the WSDL and XML Schema for Order Process Web Service , you will take the same WSDL artifact and look at how to generate the implementation stubs from WSDL and publish it.
Generating Implementation Stubs from WSDL
The JAX-WS specification provides a detail mapping from a service defined in WSDL to the Java classes that will implement that service. You already looked at how the WSDL was generated from JAX-WS annotations defined on OrderProcessService service implementation and how th Java objects (inputs ad output to service methods) were converted into XML schemas and referenced in WSDL messages based on JAXB specification. This process is the reverse of code first approach , of generating java implemetations from WSDL and Schema contracts.
Generating Implementation Stubs from WSDL
The process outlined here is similar to Creating Web Service client process described in my earlier blog, with the intention of using the generated JAX-WS artifacts for creating service implementation. As you recollect , the wsimport based on the WSDL generates the JAXB binding classes along with service interfaces from the WSDL. You will implement the service interface generated to provide your implemetation and later publish it.
For simplicity , lets generate the JAX-WS artifacts in a seperate package, navigate to bin directory which contains all the compiled class files (previously created as a result of executing compile.bat) and run the following command.
Note: Before running the wsimport command, make sure you have published the web service by running the OrderWebServicePublisher
wsimport -keep -p com.nb.beginjava6.service.contractfirst http://localhost:8080
/OrderProcessWeb/orderprocess?wsdl
Note: The artifacts generated will be same as mentioned earlier in my previous blog, in creating web service client section.
You will implement the OrderProcess service interface that generated by the wsimport tool to provided required implementation for the service.The code for service implemetation is provided below.
package com.nb.beginjava6.service.contractfirst; import javax.jws.WebService; @WebService(serviceName = "OrderProcess", portName = "OrderProcessPort", endpointInterface="com.nb.beginjava6.service.contractfirst.OrderProcessService", targetNamespace = "http://nb.com/beginjava6/orderprocess") public class OrderProcessContractService implements OrderProcessService { //The @WebMethod annotation is defined in the OrderProcessService interface. public OrderBean processOrder(OrderBean orderBean) { System.out.println("OrderProcessContractService called"); orderBean.setOrderId("BC15"); return orderBean; } }
Code: The code listing for order process contract service.
The OrderProcessContractService class implements the service interface OrderProcessService (generated by wsimport tool) and provides the @WebService annotation. The @WebService annotation attaributes defined is similar to earlier OrderProcess web service implementaion, with one more attribute , endpointInterface added to it , which defines the interface class , i.e “com.nb.beginjava6.service.contractfirst.OrderProcessService”.
You don’t need to define @WebMethod annotation for processOrder methods , as the annotation is already defined for the method in the generated OrderProcessService interface. Following code shows the listing of OrderProcessService interface.
package com.nb.beginjava6.service.contractfirst; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; /** * This class was generated by the JAXWS SI. * JAX-WS RI 2.0_02-b08-fcs * Generated source version: 2.0 * */ @WebService(name = "OrderProcessService", targetNamespace = "http://nb.com/beginjava6/orderprocess") public interface OrderProcessService { /** * * @param arg0 * @return * returns com.nb.beginjava6.service.contractfirst.OrderBean */ @WebMethod @WebResult(targetNamespace = "") <pre>@RequestWrapper(localName = "processOrder", targetNamespace = "http://nb.com/beginjava6/orderprocess", className = "com.nb.beginjava6.service.contractfirst.ProcessOrder")</pre> @ResponseWrapper(localName = "processOrderResponse", targetNamespace = "http://nb.com/beginjava6/orderprocess", className = "com.nb.beginjava6.service.contractfirst.ProcessOrderResponse") public OrderBean processOrder( @WebParam(name = "arg0", targetNamespace = "") OrderBean arg0); }
Code: The code listing for generated service interface.
The processOrder method listed above defines @RequestWrapper and @ResponseWrapper method , in addition to @WebMethod. The @RequestWrapper and @ResponseWrapper as discussed in my previous blog , wraps the input (OrderBean) and output (OrderBean) parameter of the method (processOrder) with a wrapper class , which is required for resolve overloading conflicts in document literal mode.
Publishing the Order Process Contract Web Service
The process of publishing the web service remains the same irrespective of code-first or contract first development approach.
Publish the Order Process Web Service
You don’t need to generate any JAX-WS artifacts , as you have already generated required JAX-WS artifacts by running the wsimport tool , when you imported the WSDL. Publish the Order Process Contract Web Service by running the following web service publisher client.
java com.nb.beginjava6.service.publish.OrderWebServiceContractFirstPublisher
This will publish the Order Web Service at location http://localhost:8081/OrderProcessContractWeb/orderprocess .You can verify if the web service is running by displaying the Web Services Definition Language (WSDL) generated of the Order Process web service by opening the browser and navigating to the following location:
http://localhost:8081/OrderProcessContractWeb/orderprocess?wsdl
Following provides the source code of the OrderProcessContractService The code is excalty similar to earlier code for publishing the OrderWebServicePublisher client , except the location of the web service and service implementation differ.
package com.nb.beginjava6.service.publish; import javax.xml.ws.Endpoint; import com.nb.beginjava6.service.contractfirst.OrderProcessContractService; public class OrderWebServiceContractFirstPublisher { public static void main(String[] args) { Endpoint.publish("http://localhost:8081/OrderProcessContractWeb/orderprocess", new OrderProcessContractService()); } }
Code: The code listing for publishing order process contract web service.
Generating Web Service Clients from WSDL
The process of generating web service clients doesn’t differ if you are using code-first or contract first development approach, as you generate web service clients from WSDL.
Creating Web Service Client
You can use the same web service client that you created for code-first approach. As the WSDL/Schema definitions are same for both of these services expect the soap:address location in WSDL , you will execute the same web service client by passing in the WSDL URL of the OrderProcessContractService.
Execute the web service client by providing the WSDL URL for the OrderProcessContract Service using the following command. Refer to my previous blog , about details on the OrderClient.
java com.nb.beginjava6.service.client.OrderClient
http://localhost:8081/OrderProcessContractWeb/orderprocess?wsdl
When the web service is executed, you will see the following output at the console, where the OrderWebServiceContractFirstPublisher is running.
OrderProcessContractService called
At the console where the web service client is executed, you will receive the following output.
Order id is BC15
You have successfully implemented your web services using a contract first development approach. In next blog, I would describe how to intercept SOAP messages.