JAX-WS Basic example – RPC Style


In this article, we will perform below tasks based on our requirement


Create RPC style web service using JAX-WS and expose it with end point

Create java web service client manually

Create java web service client using wsimport

Requirement:


Create a web service to find whether given number is prime or not and develop a client which consumes it.

Let’s implement this requirement with below steps


Step 1

Create a new Java project in eclipse

JAXWSPrimeNumberRPCServiceProjStructure


Step 2

Create a service endpoint interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.kb.ws;
 
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 PrimeNumberService {
    
    @WebMethod
    public boolean isPrimeNumber(int number);
}
package com.kb.ws;

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 PrimeNumberService {
	
	@WebMethod
	public boolean isPrimeNumber(int number);
}


A service endpoint interface (SEI) is a Java interface that declares the methods that a client can invoke on the service.

Client will always rely on SEI to call the web service

@WebService indicates its a service interface

@WebMethod on top of method indicates that specified method will be exposed as a service to client.

we can include multiple methods in the service but need to provide @WebMethod annotation on each method.

We have specified Binding style as RPC using @SOAPBinding annotation.

Read more about RPC and other binding style in SOAP message binding style article

Step 3

Create a service endpoint implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.kb.ws;
 
import javax.jws.WebService;
 
@WebService(endpointInterface="com.kb.ws.PrimeNumberService")
public class PrimeNumberServiceImpl implements PrimeNumberService{
 
    @Override
    public boolean isPrimeNumber(int number) {
        for(int i=2;i<=number/2;i++){
            if(number % i == 0)
                return false;
        }
        return true;
    }
 
}
package com.kb.ws;

import javax.jws.WebService;

@WebService(endpointInterface="com.kb.ws.PrimeNumberService")
public class PrimeNumberServiceImpl implements PrimeNumberService{

	@Override
	public boolean isPrimeNumber(int number) {
		for(int i=2;i<=number/2;i++){
			if(number % i == 0)
				return false;
		}
		return true;
	}

}


Here we have specified SEI using endpointInterface property of @Webervice annotation.

com.kb.ws.PrimeNumberService is defined as the end point interface which should be fully qualified name of the endpoint interface created in Step 2

we have written a logic which will check whether given number is prime number or not and returns true if number is prime and returns false if its non prime number

Step 4

Create the web service Publisher class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.kb.endpoint;
 
import javax.xml.ws.Endpoint;
 
import com.kb.ws.PrimeNumberServiceImpl;
 
public class PrimeNumberPublisher {
    public static void main(String[] args) {
        Endpoint endpoint = Endpoint.create(new PrimeNumberServiceImpl());
        endpoint.publish("http://localhost:8888/ws/primeNumber");
 
    }
 
}
package com.kb.endpoint;

import javax.xml.ws.Endpoint;

import com.kb.ws.PrimeNumberServiceImpl;

public class PrimeNumberPublisher {
	public static void main(String[] args) {
		Endpoint endpoint = Endpoint.create(new PrimeNumberServiceImpl());
		endpoint.publish("http://localhost:8888/ws/primeNumber");

	}

}


In this class we are calling create method of Endpoint class for creating the endpoint for the given implementation object.

We are also calling publish method of Endpoint class which is used to publish the endpoint

Alternative way of creating and publishing the end point is

Endpoint.publish("http://localhost:8888/ws/primeNumber", new PrimeNumberServiceImpl());

It is better to go with create and publish methods as it gives more control over server configuration.

Note:


An endpoint is either in a published or an unpublished state

Once endpoint is published, it starts accepting incoming requests.

Step 5

Run the endpoint publisher

Now Prime number service is deployed at http://localhost:8888/ws/primeNumber

Step 6

Access wsdl via the URL just by appending ?wsdl at the end of URL as below

http://localhost:8888/ws/primeNumber?wsdl

We can see below wsdl file response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!--
 Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. 
-->
<!--
 Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. 
-->
<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://ws.kb.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.kb.com/"name="PrimeNumberServiceImplService">
<types/>
 
<message name="isPrimeNumber">
     <part name="arg0" type="xsd:int"/>
</message>
 
<message name="isPrimeNumberResponse">
     <part name="return" type="xsd:boolean"/>
</message>
 
<portType name="PrimeNumberService">
    <operation name="isPrimeNumber">
      <input wsam:Action="http://ws.kb.com/PrimeNumberService/isPrimeNumberRequest" message="tns:isPrimeNumber"/>
      <output wsam:Action="http://ws.kb.com/PrimeNumberService/isPrimeNumberResponse"            
                                                                              message="tns:isPrimeNumberResponse"/>
    </operation>
</portType>
 
<binding name="PrimeNumberServiceImplPortBinding" type="tns:PrimeNumberService">
     <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
     <operation name="isPrimeNumber">
     <soap:operation soapAction=""/>
     <input>
         <soap:body use="literal" namespace="http://ws.kb.com/"/>
     </input>
     <output>
         <soap:body use="literal" namespace="http://ws.kb.com/"/>
     </output>
     </operation>
</binding>
 
<service name="PrimeNumberServiceImplService">
<port name="PrimeNumberServiceImplPort" binding="tns:PrimeNumberServiceImplPortBinding">
<soap:address location="http://localhost:8888/ws/primeNumber"/>
</port>
</service>
</definitions>
<!--
 Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. 
-->
<!--
 Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. 
-->
<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://ws.kb.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.kb.com/"name="PrimeNumberServiceImplService">
<types/>

<message name="isPrimeNumber">
     <part name="arg0" type="xsd:int"/>
</message>

<message name="isPrimeNumberResponse">
     <part name="return" type="xsd:boolean"/>
</message>

<portType name="PrimeNumberService">
    <operation name="isPrimeNumber">
      <input wsam:Action="http://ws.kb.com/PrimeNumberService/isPrimeNumberRequest" message="tns:isPrimeNumber"/>
      <output wsam:Action="http://ws.kb.com/PrimeNumberService/isPrimeNumberResponse"            
                                                                              message="tns:isPrimeNumberResponse"/>
    </operation>
</portType>

<binding name="PrimeNumberServiceImplPortBinding" type="tns:PrimeNumberService">
     <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
     <operation name="isPrimeNumber">
     <soap:operation soapAction=""/>
     <input>
         <soap:body use="literal" namespace="http://ws.kb.com/"/>
     </input>
     <output>
         <soap:body use="literal" namespace="http://ws.kb.com/"/>
     </output>
     </operation>
</binding>

<service name="PrimeNumberServiceImplService">
<port name="PrimeNumberServiceImplPort" binding="tns:PrimeNumberServiceImplPortBinding">
<soap:address location="http://localhost:8888/ws/primeNumber"/>
</port>
</service>
</definitions>


Web Service clients


Let’s create web service clients to access the deployed web service

We can create the client either manually or we can use wsimport tool to do the same

We will discuss both the options

1. Creating web service client with wsimport tool


Java provides wsimport utility tool which helps in generating the client support code by using the WSDL document.

Its available under JDK_PATH/bin folder.

Let’s use the WSDL file and generate the client files

Open command prompt and issue the below command

wsimport -keep -p client http://localhost:8888/ws/primeNumber?wsdl

-keep option specifies that it has to keep the generated files.

-p allows us to specify the java package name in which the generated files are to be placed.

We have given the package name as “client” so it will keep in client package.

Output of wsimport command

jax-ws-prime-number-wsimport-cmd-output

Now client code is generated under the path from where we issued wsimport command

We can see 2 source files and 2 class files generated in my folder

jax-ws-prime-number-wsimport-cmd-output-files

Generated files are as below

PrimeNumberService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.kb.ws.client;
 
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Action;
 
 
/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2.9-b130926.1035
 * Generated source version: 2.2
 * 
 */
@WebService(name = "PrimeNumberService", targetNamespace = "http://ws.kb.com/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface PrimeNumberService {
 
 
    /**
     * 
     * @param arg0
     * @return
     *     returns boolean
     */
    @WebMethod
    @WebResult(partName = "return")
    @Action(input = "http://ws.kb.com/PrimeNumberService/isPrimeNumberRequest", output = "http://ws.kb.com/PrimeNumberService/isPrimeNumberResponse")
    public boolean isPrimeNumber(
        @WebParam(name = "arg0", partName = "arg0")
        int arg0);
 
}
package com.kb.ws.client;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Action;


/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2.9-b130926.1035
 * Generated source version: 2.2
 * 
 */
@WebService(name = "PrimeNumberService", targetNamespace = "http://ws.kb.com/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface PrimeNumberService {


    /**
     * 
     * @param arg0
     * @return
     *     returns boolean
     */
    @WebMethod
    @WebResult(partName = "return")
    @Action(input = "http://ws.kb.com/PrimeNumberService/isPrimeNumberRequest", output = "http://ws.kb.com/PrimeNumberService/isPrimeNumberResponse")
    public boolean isPrimeNumber(
        @WebParam(name = "arg0", partName = "arg0")
        int arg0);

}


PrimeNumberServiceImplService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.kb.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.9-b130926.1035
 * Generated source version: 2.2
 * 
 */
@WebServiceClient(name = "PrimeNumberServiceImplService", targetNamespace = "http://ws.kb.com/", wsdlLocation = "http://localhost:8888/ws/primeNumber?wsdl")
public class PrimeNumberServiceImplService
    extends Service
{
 
    private final static URL PRIMENUMBERSERVICEIMPLSERVICE_WSDL_LOCATION;
    private final static WebServiceException PRIMENUMBERSERVICEIMPLSERVICE_EXCEPTION;
    private final static QName PRIMENUMBERSERVICEIMPLSERVICE_QNAME = new QName("http://ws.kb.com/", "PrimeNumberServiceImplService");
 
    static {
        URL url = null;
        WebServiceException e = null;
        try {
            url = new URL("http://localhost:8888/ws/primeNumber?wsdl");
        } catch (MalformedURLException ex) {
            e = new WebServiceException(ex);
        }
        PRIMENUMBERSERVICEIMPLSERVICE_WSDL_LOCATION = url;
        PRIMENUMBERSERVICEIMPLSERVICE_EXCEPTION = e;
    }
 
    public PrimeNumberServiceImplService() {
        super(__getWsdlLocation(), PRIMENUMBERSERVICEIMPLSERVICE_QNAME);
    }
 
    public PrimeNumberServiceImplService(WebServiceFeature... features) {
        super(__getWsdlLocation(), PRIMENUMBERSERVICEIMPLSERVICE_QNAME, features);
    }
 
    public PrimeNumberServiceImplService(URL wsdlLocation) {
        super(wsdlLocation, PRIMENUMBERSERVICEIMPLSERVICE_QNAME);
    }
 
    public PrimeNumberServiceImplService(URL wsdlLocation, WebServiceFeature... features) {
        super(wsdlLocation, PRIMENUMBERSERVICEIMPLSERVICE_QNAME, features);
    }
 
    public PrimeNumberServiceImplService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }
 
    public PrimeNumberServiceImplService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
        super(wsdlLocation, serviceName, features);
    }
 
    /**
     * 
     * @return
     *     returns PrimeNumberService
     */
    @WebEndpoint(name = "PrimeNumberServiceImplPort")
    public PrimeNumberService getPrimeNumberServiceImplPort() {
        return super.getPort(new QName("http://ws.kb.com/", "PrimeNumberServiceImplPort"), PrimeNumberService.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 PrimeNumberService
     */
    @WebEndpoint(name = "PrimeNumberServiceImplPort")
    public PrimeNumberService getPrimeNumberServiceImplPort(WebServiceFeature... features) {
        return super.getPort(new QName("http://ws.kb.com/", "PrimeNumberServiceImplPort"), PrimeNumberService.class, features);
    }
 
    private static URL __getWsdlLocation() {
        if (PRIMENUMBERSERVICEIMPLSERVICE_EXCEPTION!= null) {
            throw PRIMENUMBERSERVICEIMPLSERVICE_EXCEPTION;
        }
        return PRIMENUMBERSERVICEIMPLSERVICE_WSDL_LOCATION;
    }
 
}
package com.kb.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.9-b130926.1035
 * Generated source version: 2.2
 * 
 */
@WebServiceClient(name = "PrimeNumberServiceImplService", targetNamespace = "http://ws.kb.com/", wsdlLocation = "http://localhost:8888/ws/primeNumber?wsdl")
public class PrimeNumberServiceImplService
    extends Service
{

    private final static URL PRIMENUMBERSERVICEIMPLSERVICE_WSDL_LOCATION;
    private final static WebServiceException PRIMENUMBERSERVICEIMPLSERVICE_EXCEPTION;
    private final static QName PRIMENUMBERSERVICEIMPLSERVICE_QNAME = new QName("http://ws.kb.com/", "PrimeNumberServiceImplService");

    static {
        URL url = null;
        WebServiceException e = null;
        try {
            url = new URL("http://localhost:8888/ws/primeNumber?wsdl");
        } catch (MalformedURLException ex) {
            e = new WebServiceException(ex);
        }
        PRIMENUMBERSERVICEIMPLSERVICE_WSDL_LOCATION = url;
        PRIMENUMBERSERVICEIMPLSERVICE_EXCEPTION = e;
    }

    public PrimeNumberServiceImplService() {
        super(__getWsdlLocation(), PRIMENUMBERSERVICEIMPLSERVICE_QNAME);
    }

    public PrimeNumberServiceImplService(WebServiceFeature... features) {
        super(__getWsdlLocation(), PRIMENUMBERSERVICEIMPLSERVICE_QNAME, features);
    }

    public PrimeNumberServiceImplService(URL wsdlLocation) {
        super(wsdlLocation, PRIMENUMBERSERVICEIMPLSERVICE_QNAME);
    }

    public PrimeNumberServiceImplService(URL wsdlLocation, WebServiceFeature... features) {
        super(wsdlLocation, PRIMENUMBERSERVICEIMPLSERVICE_QNAME, features);
    }

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

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

    /**
     * 
     * @return
     *     returns PrimeNumberService
     */
    @WebEndpoint(name = "PrimeNumberServiceImplPort")
    public PrimeNumberService getPrimeNumberServiceImplPort() {
        return super.getPort(new QName("http://ws.kb.com/", "PrimeNumberServiceImplPort"), PrimeNumberService.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 PrimeNumberService
     */
    @WebEndpoint(name = "PrimeNumberServiceImplPort")
    public PrimeNumberService getPrimeNumberServiceImplPort(WebServiceFeature... features) {
        return super.getPort(new QName("http://ws.kb.com/", "PrimeNumberServiceImplPort"), PrimeNumberService.class, features);
    }

    private static URL __getWsdlLocation() {
        if (PRIMENUMBERSERVICEIMPLSERVICE_EXCEPTION!= null) {
            throw PRIMENUMBERSERVICEIMPLSERVICE_EXCEPTION;
        }
        return PRIMENUMBERSERVICEIMPLSERVICE_WSDL_LOCATION;
    }

}


wsimport has generated the interface PrimeNumberService which has the same method as the original method inside PrimeNumberService at server side.

PrimeNumberServiceImplService has a no-argument constructor that will be used to construct the Service object

PrimeNumberServiceImplService has a method getPrimeNumberServiceImplPort () that returns instance of PrimeNumberService on which service methods has to be called.

Let’s create another java project in eclipse for web service client and copy these generated client files

Just change the package inside java files accordingly

JAXWSPrimeNumberRPCClientProjStructure

Create the client class and call the web service using above generated files
PrimeNumberClient.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.kb.ws.client;
 
public class PrimeNumberClient {
    public static void main(String[] args) {
        PrimeNumberServiceImplService service = new PrimeNumberServiceImplService();
        PrimeNumberService primeNumberService = service.getPrimeNumberServiceImplPort();
                 
         System.out.println(primeNumberService.isPrimeNumber(13));
         
         System.out.println(primeNumberService.isPrimeNumber(14));
 
    }
 
}
package com.kb.ws.client;

public class PrimeNumberClient {
	public static void main(String[] args) {
		PrimeNumberServiceImplService service = new PrimeNumberServiceImplService();
		PrimeNumberService primeNumberService = service.getPrimeNumberServiceImplPort();
		         
		 System.out.println(primeNumberService.isPrimeNumber(13));
		 
		 System.out.println(primeNumberService.isPrimeNumber(14));

	}

}


Output

2. Creating web service client manually without wsimport tool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.kb.ws.client;
 
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
 
public class PrimeNumberManualClient {
    public static void main(String[] args) throws Exception {
        URL url = new URL("http://localhost:8888/ws/primeNumber?wsdl");
 
        QName qname = new QName("http://ws.kb.com/", "PrimeNumberServiceImplService");
 
        Service service = Service.create(url, qname);
 
        PrimeNumberService primeNumberService = service.getPort(PrimeNumberService.class);
 
        System.out.println(primeNumberService.isPrimeNumber(13));
        System.out.println(primeNumberService.isPrimeNumber(14));
    }
 
}
package com.kb.ws.client;

import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class PrimeNumberManualClient {
	public static void main(String[] args) throws Exception {
		URL url = new URL("http://localhost:8888/ws/primeNumber?wsdl");

		QName qname = new QName("http://ws.kb.com/", "PrimeNumberServiceImplService");

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

		PrimeNumberService primeNumberService = service.getPort(PrimeNumberService.class);

		System.out.println(primeNumberService.isPrimeNumber(13));
		System.out.println(primeNumberService.isPrimeNumber(14));
	}

}


Under QName, need to pass 2 arguments

1st argument is service URI same as targetNamespace in the wsdl

2nd argument is service name which is PrimeNumberServiceImplService as we can see in the WSDL.

Output

Download both client and service projects JAXWSPrimeNumberRPC.zip

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on