JAX-WS webservice example

Introduction

I am going to give an example on how to create a SOAP based jax-ws webservice. I will show you how to publish the service in two approaches. First approach for publishing the service will be just using the java main method. Second approach will be by deploying the service in Tomcat Server 7 in another tutorial. We will use here JAX-WS API to create SOAP based webservice. We are using gradle to build our application. If you want to use maven you can read the example here.

Prerequisites

Eclipse Neon, Java at least 1.8, Gradle 5.4.1/6.1.1, JAX-WS 2.3.1

Creating Project

Create a gradle based project in Eclipse. The name of the project is jax-ws.

Updating Build File

We need to update the build file for including required dependencies in build.gradle file.

plugins {
    id 'java-library'
}
sourceCompatibility = 12
targetCompatibility = 12
repositories {
    mavenCentral()
	maven {
		url 'http://maven.java.net/content/repositories/staging/'
	}
}
dependencies {
    implementation 'javax.xml.ws:jaxws-api:2.3.1'
    implementation 'com.sun.xml.ws:jaxws-rt:2.3.1'
    implementation 'org.glassfish.jaxb:txw2:2.4.0-b180608.0325'
}

Creating End-point Interface

Create an interface that will act as an endpointInterface.

package com.roytuts.jax.ws.service;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
@SOAPBinding(style = Style.RPC)
public interface Hello {
	@WebMethod
	public String sayHello(String name);
}

End-point Interface Implementation

endpointInterface attribute is used to separate between the implementing class and the interface. Basically, this determines what will be mapped to wsdl:portType when the service is deployed and the wsdl:definition is generated.

If you do not define the endpointInterface all public methods of the annotated class will be mapped to wsdl:operation.

If you define the endpointInterface, it has to point to some type which the annotated class implements. Then, the public methods of this type are used for mapping the wsdl:portType, instead of the methods of the annotated class.

package com.roytuts.jax.ws.service.impl;
import javax.jws.WebService;
import com.roytuts.jax.ws.service.Hello;
@WebService(endpointInterface = "com.roytuts.jax.ws.service.Hello")
public class HelloImpl implements Hello {
	@Override
	public String sayHello(String name) {
		return "Hello " + name;
	}
}

Webservice Publisher

Now we need to publish the service in order to access the service from the client.

The URL format should be http://<host>:<port>/<any path name>/<any service name>, i.e. http://localhost:8888/jax-ws/hello

WSDL location should be http://<host>:<port>/<any path name>/<any service name>?wsdl, i.e., http://localhost:8888/jax-ws/hello?wsdl

package com.roytuts.jax.ws.service.publisher;
import javax.xml.ws.Endpoint;
import com.roytuts.jax.ws.service.impl.HelloImpl;
public class HelloPublisher {
	public static void main(String[] args) {
		Endpoint.publish("http://localhost:8888/jax-ws/hello", new HelloImpl());
	}
}

Webservice Consumer

Now we need to test the service, so we create consumer class for that.

package com.roytuts.jax.ws.service.consumer;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import com.roytuts.jax.ws.service.Hello;
public class HelloConsumer {
	public static void main(String[] args) throws MalformedURLException {
		URL url = new URL("http://localhost:8888/jax-ws/hello?wsdl");
		QName qname = new QName("http://impl.service.ws.jax.roytuts.com/", "HelloImplService");
		Service service = Service.create(url, qname);
		Hello hello = service.getPort(Hello.class);
		System.out.println(hello.sayHello("Soumitra"));
	}
}

Testing the Application

Run the HelloPublisher class first. The SOAP webservice will be published on port 8888.

Now run the class HelloConsumer, you will see below output in the console.

Hello Soumitra

Accessing WSDL File

Hit the URL http://localhost:8888/jax-ws/hello?wsdl in the browser, you will below WSDL file in the browser.

<?xml version='1.0' encoding='UTF-8'?><!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.3.1 svn-revision#6ef5f7eb9a938dbc4562f25f8fa0b67cc4ff2dbb. --><!-- Generated by JAX-WS RI (http://javaee.github.io/metro-jax-ws). RI's version is JAX-WS RI 2.3.1 svn-revision#6ef5f7eb9a938dbc4562f25f8fa0b67cc4ff2dbb. --><definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://impl.service.ws.jax.roytuts.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://impl.service.ws.jax.roytuts.com/" name="HelloImplService">
<import namespace="http://service.ws.jax.roytuts.com/" location="http://localhost:8888/jax-ws/hello?wsdl=1"/>
	<binding xmlns:ns1="http://service.ws.jax.roytuts.com/" name="HelloImplPortBinding" type="ns1:Hello">
		<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
		<operation name="sayHello">
			<soap:operation soapAction=""/>
			<input>
				<soap:body use="literal" namespace="http://service.ws.jax.roytuts.com/"/>
			</input>
			<output>
				<soap:body use="literal" namespace="http://service.ws.jax.roytuts.com/"/>
			</output>
		</operation>
	</binding>
	<service name="HelloImplService">
		<port name="HelloImplPort" binding="tns:HelloImplPortBinding">
			<soap:address location="http://localhost:8888/jax-ws/hello"/>
		</port>
	</service>
</definitions>

Now you can use this WSDL file to consume the service from another system. Just generate stub or client java code from the WSDL file and invoke the service. We will see later how to consume webservice.

Source Code

Download Source Code

Thanks for your reading.

Leave a Comment