Monday 21 November 2016

Java Source World: Creating SOAP Web Services using JAX-WS

Creating SOAP Web Services using JAX-WS | Java Source World

                                                   



Creating SOAP Web Services using JAX-WS in Tomcat:



Publish or deploy SOAP based web services in Tomcat:



This post will explain you how to create SOAP-based web services using JAX-WS API and deploy it with tomat server.




There are various ways of creating web services. In this post we are going to create a SOAP based web service using JAX-WS, which is Java API for XML Web Services and we will deploy it under Tomcat.





One important point to remember is, both SOAP and REST style web services can be built using JAX-WS. There is a common misconception that JAX-WS is used for creating SOAP based web services and JAX-RS is used for creating REST style web services.



JAX-WS API is very rich and provides a handful of annotations to make developers life easy.



Different styles of SOAP based Web Service


SOAP based web services can be categorized as: 

RPC Style – RPC style is used for creating SOAP web services which includes simple data types (Built-in types)

Document Style –  This is the default style and used to create SOAP web services containing complex data types.



FindAirportNames Webservice:

We are goint to create and publish soap based web service named findAirportNames.

This webservice will provide us the list of airport names which are available in the country, country name is the input for this service as string format.

For example, If we pass the two letter country code as "IN" then the response will show the list of airport names: as: DEL(Delhi), BLR(Bangalore) etc..,

As of now in this post we are going to publish our service, then in the later post we will talk about the consuming the service.

Now here we will see the sample illustration of how the consumer requests the service and get the response.

Fig: Web Services flow


Here we are going to start implementing our service.

First we need to have an interface, that is called SEI(Service Endpoint Interface).



AirportService.java

package com.javasourceworld.webservice;

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

@WebService
public interface AirportService {
      @WebMethod
      String findAirportNames(String countryCode);
}



AirportServiceImpl.java is the implementation class of the service class AirportService.java, and we have to provide the implementation code to the abstract method findAirportNames().


AirportServiceImpl.java

package com.javasourceworld.webservice;

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

@WebService(endpointInterface = "com.javasourceworld.webservice.AirportService")
public class AirportServiceImpl implements AirportService{

       AirportUtility utility;
      
       public AirportServiceImpl(){
              utility = new AirportUtility();
              utility.loadAirports();
       }

       @Override
       @WebMethod
       public  String findAirportNames(String countryCode) {
              Airport airport = utility.findAirports(countryCode);
              StringBuilder bd = new StringBuilder();
              bd.append("Airport Name: ").append(" ").
                           append(airport.getAirportCode()).append(" ").
                           append("City Name: ").append(airport.getCityName());
              return bd.toString();
       }
      
      
}



In the service implementation class, we have an utility method which loads and stores the information of the list of airports to show to the response.

Here we have Airport.java which has the properties and their set and get methods and has parameterized constructor to create an object for that class.



Airport.java


package com.javasourceworld.webservice;

public class Airport {
       private String airportCode;
       private String cityName;
      
       public Airport(){
             
       }
       public Airport(String arpcod, String cityName){
              this.airportCode = arpcod;
              this.cityName = cityName;
       }
      
       public String getAirportCode() {
              return airportCode;
       }
       public void setAirportCode(String airportCode) {
              this.airportCode = airportCode;
       }
       public String getCityName() {
              return cityName;
       }
       public void setCityName(String cityName) {
              this.cityName = cityName;
       }
}


And we have an utility class AirportUtility.java, which has HashMap<String, Airport> which stores airport details as values and String as a key. In this example Key could be Country code.

AirportUtility.java

package com.javasourceworld.webservice;

import java.util.HashMap;


public class AirportUtility {

       HashMap<String, Airport> airportMap = new HashMap<String, Airport>();
       public void loadAirports(){
             
              Airport euairport = new Airport("FRA","Frankfurt");
              Airport usairport = new Airport("ATL","Atlanta");
              Airport inairport = new Airport("DEL","Delhi");
             
              airportMap.put("EU", euairport);
              airportMap.put("US", usairport);
              airportMap.put("IN", inairport);
       }
      
       public Airport findAirports(String countryCode){
              Airport airport = null;
              airport = airportMap.get(countryCode);
              return airport;
       }
}

The utility class has the method loadAirports() to construct the airport objects into the corresponding Map  with the String keys. When the method findAirports() gets called then the loaded airport object could be retrieved for the corresponding key.

Till now we have written our Service endpoint interface(SEI), and the corresponding implementation class, and an utility class which constructs and saves the airport info in the map object.

Now we have done with the java code, to publish a service we need to configure that service in the web.xml


Configuring the Web Service:

Since we are going to deploy the service in the web container in the case of Apache tomcat server, we have to configure our service in the web.xml file as shown below.

<listener>
        <listener-class>
            com.sun.xml.ws.transport.http.servlet.WSServletContextListener
        </listener-class>
   </listener>
<servlet>
        <servlet-name>webservice</servlet-name>
        <servlet-class>
            com.sun.xml.ws.transport.http.servlet.WSServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
        <servlet-name>webservice</servlet-name>
        <url-pattern>/findAirportNames</url-pattern>
</servlet-mapping>


One more configuration is required is to creating a file sun-jaxws.xml in the WEB-INF folder which defines the Service implementation class.


sun-jaxws.xml

<?xml version="1.0" encoding="UTF-8"?>
<endpoints
  xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
  version="2.0">
  <endpoint
      name="WebServiceImpl"
      implementation="com.javasourceworld.webservice.AirportServiceImpl"
      url-pattern="/findAirportNames"/>
</endpoints>




Note that you will require extra jax-ws libraries to publish SOAP based web service under Tomcat. You can download these libraries from jax-ws.net and put them in the WEB-INF/lib folder.


Now run the project and your web service will be deployed and available at whatever URL you mentioned in web.xml file (in this case /findAirportNames).

Note: url-pattern must be same in both the files web.xml, and sun-jaxws.xml.


Now here we will see the project structure in eclipse.




Now right click on the webservices project and select Run as and choose the Run on server option, once the server is started url publishes our service as shown below.



To access the published WSDL file, click on the WSDL:   

http://localhost:8091/webservices/findAirportNames?wsdl, then you can see the wsdl skeleton as shown below.


WSDL:








Once the web service is published you can write a client against web service in any language Python, Perl, C#, Java etc.

That’s the beauty of web services, they are language independent. Let’s write a Java client to consume the web service.


Web service consumption post will be posted soon....



Posts you may like to read:


Introduction to SOAP based Web Services

Differences between SOAP and REST Web Services
java.lang.NoSuchMethodError: javax.xml.ws.WebFault.messageName()Ljava/lang/String


                                                 










No comments:

Post a Comment