JAX-WS Endpoint Example
In this example we shall see how to use JAX-WS Endpoint. Literally talking about web service endpoint, it is a resource that is to be referred and to which web service message should be addressed.
This endpoint can either be in published or unpublished state and JAX-WS’s Endpoint
class is used to achieve this purpose. Endpoint
class has 2 important methods publish()
used to publish or start the web service, and stop()
used to un-publish or stop the web service.
To understand this concept in detail let’s first understand the two considerable terms SEI (Service Endpoint Interface) and SIB (Service Implementation Bean).
To implement a SOAP based web service using JAX-WS API’s, it could be done using a single class but as the best practices tells us, we should first define an interface that declares all the methods to be exposed as a Web Service, and its implementation should define those methods. The interface in question is SEI and the implementation is SIB.
Proceeding now to the code:
1. Implementing Web Service
1.1 Writing Service Endpoint Interface
CalculatorServer.java:
package com.javacodegeeks.examples.endpoint; import javax.jws.WebMethod; import javax.jws.WebService; @WebService public interface CalculatorServer { @WebMethod int sum(int a, int b); @WebMethod int diff(int a, int b); @WebMethod int multiply(int a, int b); @WebMethod int divide(int a, int b); }
1.2 Writing Service Implementation Bean
CalculatorServerImpl.java:
package com.javacodegeeks.examples.endpoint; import javax.jws.WebService; @WebService(endpointInterface = "com.javacodegeeks.examples.endpoint.CalculatorServer") public class CalculatorServerImpl implements CalculatorServer { @Override public int sum(int a, int b) { return a+b; } @Override public int diff(int a, int b) { return a-b; } @Override public int multiply(int a, int b) { return a*b; } @Override public int divide(int a, int b) { return a/b; } }
As we see here this class is implementation of Service Endpoint Interface.
2. Publishing Web Service
CalculatorServerPublisher.java:
package com.javacodegeeks.examples.endpoint; import javax.xml.ws.Endpoint; public class CalculatorServerPublisher { public static void main(String[] args) { Endpoint ep = Endpoint.create(new CalculatorServerImpl()); ep.publish("http://127.0.0.1:10000/calcServer"); //Do something //Comment below line if service is meant to be running always ep.stop(); } }
Notice in the above program, we are using Endpoint’s class static method create()
to get its instance. On this instance, we call publish()
method to start the web service, or in other words, we are creating an endpoint here. create()
method used in above example accepts one argument that is the service implementation bean instance. publish()
method used here accepts one argument that is he URI specifying the address and protocol to be used.
There’s another method stop()
used in above example whose purpose is to stop publishing the endpoint.
Another way to publish web service is using Endpoint’s class static publish()
method as follows:
Endpoint.publish("http://127.0.0.1:10000/calcServer", new CalculatorServerImpl());
On starting this main program, a java service shall get started and following kind of message shall get displayed in the console on successful publishing of web service:
Nov 28, 2015 8:18:11 PM com.sun.xml.internal.ws.model.RuntimeModeler getRequestWrapperClass INFO: Dynamically creating request wrapper Class com.javacodegeeks.examples.endpoint.jaxws.Multiply Nov 28, 2015 8:18:11 PM com.sun.xml.internal.ws.model.RuntimeModeler getResponseWrapperClass INFO: Dynamically creating response wrapper bean Class com.javacodegeeks.examples.endpoint.jaxws.MultiplyResponse Nov 28, 2015 8:18:11 PM com.sun.xml.internal.ws.model.RuntimeModeler getRequestWrapperClass INFO: Dynamically creating request wrapper Class com.javacodegeeks.examples.endpoint.jaxws.Divide Nov 28, 2015 8:18:11 PM com.sun.xml.internal.ws.model.RuntimeModeler getResponseWrapperClass INFO: Dynamically creating response wrapper bean Class com.javacodegeeks.examples.endpoint.jaxws.DivideResponse Nov 28, 2015 8:18:11 PM com.sun.xml.internal.ws.model.RuntimeModeler getRequestWrapperClass INFO: Dynamically creating request wrapper Class com.javacodegeeks.examples.endpoint.jaxws.Sum Nov 28, 2015 8:18:11 PM com.sun.xml.internal.ws.model.RuntimeModeler getResponseWrapperClass INFO: Dynamically creating response wrapper bean Class com.javacodegeeks.examples.endpoint.jaxws.SumResponse Nov 28, 2015 8:18:11 PM com.sun.xml.internal.ws.model.RuntimeModeler getRequestWrapperClass INFO: Dynamically creating request wrapper Class com.javacodegeeks.examples.endpoint.jaxws.Diff Nov 28, 2015 8:18:11 PM com.sun.xml.internal.ws.model.RuntimeModeler getResponseWrapperClass INFO: Dynamically creating response wrapper bean Class com.javacodegeeks.examples.endpoint.jaxws.DiffResponse
3. Checking WSDL file for endpoint definition
The WSDL file for this example can be accessed at URL:
http://127.0.0.1:10000/calcServer?wsdl
Here is how the WSDL file for this example would look like:
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://endpoint.examples.javacodegeeks.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://endpoint.examples.javacodegeeks.com/" name="CalculatorServerImplService"> <types> <xsd:schema> <xsd:import namespace="http://endpoint.examples.javacodegeeks.com/" schemaLocation="http://127.0.0.1:10000/calcServer?xsd=1" /> </xsd:schema> </types> <message name="multiply"> <part name="parameters" element="tns:multiply" /> </message> <message name="multiplyResponse"> <part name="parameters" element="tns:multiplyResponse" /> </message> <message name="divide"> <part name="parameters" element="tns:divide" /> </message> <message name="divideResponse"> <part name="parameters" element="tns:divideResponse" /> </message> <message name="sum"> <part name="parameters" element="tns:sum" /> </message> <message name="sumResponse"> <part name="parameters" element="tns:sumResponse" /> </message> <message name="diff"> <part name="parameters" element="tns:diff" /> </message> <message name="diffResponse"> <part name="parameters" element="tns:diffResponse" /> </message> <portType name="CalculatorServer"> <operation name="multiply"> <input message="tns:multiply" /> <output message="tns:multiplyResponse" /> </operation> <operation name="divide"> <input message="tns:divide" /> <output message="tns:divideResponse" /> </operation> <operation name="sum"> <input message="tns:sum" /> <output message="tns:sumResponse" /> </operation> <operation name="diff"> <input message="tns:diff" /> <output message="tns:diffResponse" /> </operation> </portType> <binding name="CalculatorServerImplPortBinding" type="tns:CalculatorServer"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="multiply"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> <operation name="divide"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> <operation name="sum"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> <operation name="diff"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <service name="CalculatorServerImplService"> <port name="CalculatorServerImplPort" binding="tns:CalculatorServerImplPortBinding"> <soap:address location="http://127.0.0.1:10000/calcServer" /> </port> </service> </definitions>
Notice the highlighted Service tag in the above WSDL file. This tag represents endpoint(s) where the service’s functionality is available.
4. Multithreading the endpoint publisher
The endpoint publisher that we configured above is single threaded and hence, can only handle one request at a time. In the actual or production environment, endpoint publisher shall be serving many concurrent requests.
To achieve this purpose, jax-ws provides api to set executor to the endpoint. This means that Executor shall be used to dispatch any incoming request to the service implementor.
Following is the sample program demonstrating this functionality:
CalculatorServerMultiThreadedImpl.java:
package com.javacodegeeks.examples.endpoint; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.xml.ws.Endpoint; public class CalculatorServerMultiThreadedImpl { public static void main(String[] args) { ExecutorService es = Executors.newFixedThreadPool(5); Endpoint ep = Endpoint.create(new CalculatorServerImpl()); ep.setExecutor(es); ep.publish("http://127.0.0.1:10000/calcServer"); } }
Notice in the above program, we have used api setExecutor()
to set the appropriate ThreadPool implementation.
Rest everything related to publishing the web service remains same.
5. Directory structure of the JAX-WS Endpoint Example
The directory structure of the above example in eclipse shall look like:
6. Download the Source Code
This was an example of publishing a SOAP Web Service using Endpoint
class.
You can download the full source code of this example here: EndpointExample