A Simple Document Style Web Service and Client using JAX-WS

Open Eclipse create a new Dynamic Web project.

Creating and deploying Web Service

Create your Web Service interface :
In src folder of your project create Web Service interface.

package sample.ws;

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

@WebService
public interface Greeting {
	@WebMethod
	String sayHello();
}

The @WebService annotation defines the Greeting class as a Web Service Endpoint Interface(SEI).

Create your Web Service implementation :

Specify the interface HelloWorld by adding the Endpoint Interface element to the @WebService annotation in the implementation class GreetingImpl. You must provide the full package name of the interface.

Read more: http://mrbool.com/an-introduction-to-java-web-services-programming/28116#ixzz2zCrv0Gzh

package sample.ws;

import javax.jws.WebService;

@WebService(endpointInterface = "sample.ws.Greeting")
public class GreetingImpl implements Greeting {

	@Override
	public String sayHello() {
		return "Hello, Welcom to jax-ws";
	}

}

The web service is ready for deployment.

  • You can deploy this in two ways
  • Standalone deployment :

JAX-WS based web services normally run on a JEE web container or application server. That’s great for production purposes, as those servers provide a very high level of scalability, security infrastructure, monitoring facilities etc.

But during development repeated deployments to a JEE container can be rather time consuming. JAX-WS’ Endpoint class provides an interesting alternative here, as it allows to host JAX-WS web services within plain Java SE applications.

A web service hosted that way can very easily be launched and debugged from within your IDE for instance, which is great for development and testing purposes.

If you go with the code-first approach for web service development, things are really straight-forward.

In this approach, you just need to have a main method and call the Endpoint.publish(url, provider) . This is mentioned below. This creates web service run-time environment that shipped with Java SE 6 and deploys it into light-weight http server. The service is accessible with the url provided as input to the publish method.

package sample.ws.client;

import javax.xml.ws.Endpoint;

import sample.ws.GreetingImpl;

public class PublishGreetingServiceWithEndPoint {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Endpoint.publish("http://localhost:8080/MyWebServices/greeting", new GreetingImpl());
	}

}

For more info http://musingsofaprogrammingaddict.blogspot.in/2009/04/using-jax-ws-endpoint-api.html

  • Deployment on to a servlet-container :

In this approach, we can deploy the web service by creating a standard java web application .war file and deploying that to a web server which has got a servlet container support, such as Tomcat.

You need generate Web Services classes, open your command line, and type :

cd E:\workspace\MyWebServices

wsgen -s src -d build/classes -cp build/classes sample.ws.GreetingImpl

now you have two classe(SayHello.java, SayHelloResponse.java) generated under src/sample/ws/jaxws.

Now we need to write our web.xml and put it under /WebContent/WEB-INF :

<?xml version="1.0" encoding="UTF-8"?>
<web-app
     xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
     version="2.4">
   <listener>
     <listener-class>
        com.sun.xml.ws.transport.http.servlet.WSServletContextListener
     </listener-class>
   </listener>
   <servlet>
      <servlet-name>GreetingWS</servlet-name>
      <servlet-class>
        com.sun.xml.ws.transport.http.servlet.WSServlet
      </servlet-class>

   </servlet>
   <servlet-mapping>
     <servlet-name>GreetingWS</servlet-name>
     <url-pattern>/greeting</url-pattern>
   </servlet-mapping>
</web-app>      
  • WSServletContenxtListener :

The listener class(com.sun.xml.ws.transport.http.servlet.WSServletContextListener) mentioned above is the web service context listener, which initializes the web service context when the application context is initialized and creates a web service delegate which is used to delegate all future web service requests and route them to appropriate end point implementation defined in the sun-jaxws.xml mentioned below. This stores the created delegate in the container servlet context, so that the delegate can be accessed by other servlets.

  • WSServlet :

The servlet definition and it’s mapping is used to intercept the url-pattern that should be considered as web service request.

The class(com.sun.xml.ws.transport.http.servlet.WSServlet) acts as a dispatching servlet that routes the request to appropriate implementation class through the delegate received from the servlet context created by the listener as stated above.

Add sun-jaxws.xml under WebContent :
This file is needed by the JAX-WS reference implementation to map the service implementation class with the service interface. The content of this file is mentioned below.

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
  <endpoint
     name="GreetingWS"
     implementation="sample.ws.GreetingImpl"
     url-pattern="/greeting"/>
</endpoints>
  • sun-jaxws.xml descriptor:

Each endpoint definition, in this descriptor indicates the name of the web service, implementation class and the url-pattern that routes to this web service invocation. This is read by the context listener and handed-over to the web service delegate created by it, so that the delegate knows which implementation class to invoke when a web service request came-in.

sun-jaxws.xml is a proprietary deployment descriptor needed when web services are deployed as a standard WAR archive on a non-Java EE5 servlet container using the SUN’s reference implementation.

Sun’s RI uses WSServletContextListener as the listener for servlet context events and WSServlet as the dispatcher servlet; both of which have to be declared in web.xml. The sun-jaxws.xml file is then required to define web service end points for the WSServlet to let it know to which end point a service request must be dispatched.

In this way, web services can be run in any JAX-WS RI enabled servlet container, although they won’t be portable.

Java EE 5+ compliant application servers such as Glassfish, the reference implementation, comply to JSR 109 (Web services 1.2/1.3) and JSR 224 (JAX-WS 2.0/2.1/2.2) and do not require non-standard sun-jaxws.xml deployment descriptors.

For more info http://stackoverflow.com/questions/12581751/sun-jaxws-xml-when-is-it-needed-and-when-not

Now you need to download JAX-WS library and put jars under WebContent/WEB-INF/lib :

Download from : https://jax-ws.java.net/

Great, now you just need to export this project as a war, and drop it under your Tomcat webapps folder.

Run Tomcat

Test the deployment by invoking http://localhost:8080/MyWebServices/greeting?wsdl
You will get wsdl file on browser.

Creating Consumer(Client) to access exposed methods

  • There are two ways to create client :
  • By writing cleint code

Specify the URL :

url = new URL("http://localhost:8080/MyWebServices/greeting?wsdl");

Specify the qualified namespace :

QName qname = new QName("http://ws.sample/", "GreetingImplService");

It consists of two parameters (namespaceURI and localPart) :

  • namespaceURI is the @namespace value in the WSDL file
  • The localPart is the value of the service[@name] attribute at the bottom of WSDL

 

Using the url and qualified name create the service.

Service service = Service.create(url, qname);

Get the port(proxy to the service), and interact with the webservice.

Greeting hello = service.getPort(Greeting.class);
hello.sayHello();

Complete file looks like below :

package sample.ws.client;

import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class GreetingServiceClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		URL url;
		try {
			url = new URL("http://localhost:8080/MyWebServices/greeting?wsdl");
			QName qname = new QName("http://ws.sample/", "GreetingImplService");

			Service service = Service.create(url, qname);

			Greeting hello = service.getPort(Greeting.class);

			System.out.println(hello.sayHello());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}

	}

}

Java Web Service Client via wsimport tool

We can use “wsimport” tool to parse the published wsdl file, and generate necessary client files (stub) to access the published web service.

Open the command prompt and issue the following command to generate the files :

wsimport -s src -d bin -p sample.ws.client http://localhost:8080/MyWebServices/greeting?wsdl

This will generate, one interface and one service implementation file as follows :

package sample.ws.client;

import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;


/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2.4-b01
 * Generated source version: 2.2
 * 
 */
@WebService(name = "Greeting", targetNamespace = "http://ws.sample/")
@XmlSeeAlso({
    ObjectFactory.class
})
public interface Greeting {


    /**
     * 
     * @return
     *     returns java.lang.String
     */
    @WebMethod
    @WebResult(targetNamespace = "")
    @RequestWrapper(localName = "sayHello", targetNamespace = "http://ws.sample/", className = "sample.ws.client.SayHello")
    @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://ws.sample/", className = "sample.ws.client.SayHelloResponse")
    public String sayHello();

}

package sample.ws.client;

import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;


/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2.4-b01
 * Generated source version: 2.2
 * 
 */
@WebServiceClient(name = "GreetingImplService", targetNamespace = "http://ws.sample/", wsdlLocation = "http://localhost:8080/MyWebServices/greeting?wsdl")
public class GreetingImplService
    extends Service
{

    private final static URL GREETINGIMPLSERVICE_WSDL_LOCATION;
    private final static WebServiceException GREETINGIMPLSERVICE_EXCEPTION;
    private final static QName GREETINGIMPLSERVICE_QNAME = new QName("http://ws.sample/", "GreetingImplService");

    static {
        URL url = null;
        WebServiceException e = null;
        try {
            url = new URL("http://localhost:8080/MyWebServices/greeting?wsdl");
        } catch (MalformedURLException ex) {
            e = new WebServiceException(ex);
        }
        GREETINGIMPLSERVICE_WSDL_LOCATION = url;
        GREETINGIMPLSERVICE_EXCEPTION = e;
    }

    public GreetingImplService() {
        super(__getWsdlLocation(), GREETINGIMPLSERVICE_QNAME);
    }

    public GreetingImplService(WebServiceFeature... features) {
        super(__getWsdlLocation(), GREETINGIMPLSERVICE_QNAME, features);
    }

    public GreetingImplService(URL wsdlLocation) {
        super(wsdlLocation, GREETINGIMPLSERVICE_QNAME);
    }

    public GreetingImplService(URL wsdlLocation, WebServiceFeature... features) {
        super(wsdlLocation, GREETINGIMPLSERVICE_QNAME, features);
    }

    public GreetingImplService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public GreetingImplService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
        super(wsdlLocation, serviceName, features);
    }

    /**
     * 
     * @return
     *     returns Greeting
     */
    @WebEndpoint(name = "GreetingImplPort")
    public Greeting getGreetingImplPort() {
        return super.getPort(new QName("http://ws.sample/", "GreetingImplPort"), Greeting.class);
    }

    /**
     * 
     * @param features
     *     A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values.
     * @return
     *     returns Greeting
     */
    @WebEndpoint(name = "GreetingImplPort")
    public Greeting getGreetingImplPort(WebServiceFeature... features) {
        return super.getPort(new QName("http://ws.sample/", "GreetingImplPort"), Greeting.class, features);
    }

    private static URL __getWsdlLocation() {
        if (GREETINGIMPLSERVICE_EXCEPTION!= null) {
            throw GREETINGIMPLSERVICE_EXCEPTION;
        }
        return GREETINGIMPLSERVICE_WSDL_LOCATION;
    }

}

Create a Java web service client which depends on the above generated files :

package sample.ws.client;

public class GreetingServiceClientFromWsImport {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		GreetingImplService greetingImplService = new GreetingImplService();
		Greeting greeting = greetingImplService.getGreetingImplPort();
		System.out.println(greeting.sayHello());
	}

}

For more info http://mrbool.com/an-introduction-to-java-web-services-programming/28116

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s