We learned how to use JAX-WS to create SOAP web services and publish it using javax.xml.ws.Endpoint
but most of the times we want to deploy our services on a servlet container. So today we will learn how to create a web service and deploy it on Apache Tomcat server and then test it out with the client application.
For this, our first step is to create a Dynamic Web Project to write our business logic. Our final project will look like below image.
For JAX-WS web service deployment on a servlet container, we need to add some jar files into it. There are two ways to do this.
- Download jar files from https://jax-ws.java.net/ and include it in the dynamic web project.
- Convert Dynamic web project into Maven and add below dependencies.
1234567<dependency><groupId>com.sun.xml.ws</groupId><artifactId>jaxws-rt</artifactId><version>2.2.10</version></dependency>
This will automatically download all the required jar files as maven dependencies shown in the below image. I like this approach because I can upgrade the versions easily and it will also make sure none of the jars are getting missed.
Now let’s go through the business logic. First, we will create a model bean class.
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 |
package com.journaldev.jaxws.beans; import java.io.Serializable; public class Person implements Serializable{ private static final long serialVersionUID = -5577579081118070434L; private String name; private int age; private int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString(){ return id+"::"+name+"::"+age; } } |
Now we will create our service interface and implementation classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.journaldev.jaxws.service; import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import com.journaldev.jaxws.beans.Person; @WebService @SOAPBinding(style = SOAPBinding.Style.RPC) public interface PersonService { @WebMethod public boolean addPerson(Person p); @WebMethod public boolean deletePerson(int id); @WebMethod public Person getPerson(int id); @WebMethod public Person[] getAllPersons(); } |
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 |
package com.journaldev.jaxws.service; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.jws.WebService; import com.journaldev.jaxws.beans.Person; @WebService(endpointInterface = "com.journaldev.jaxws.service.PersonService") public class PersonServiceImpl implements PersonService { private static Map<Integer,Person> persons = new HashMap<Integer,Person>(); @Override public boolean addPerson(Person p) { if(persons.get(p.getId()) != null) return false; persons.put(p.getId(), p); return true; } @Override public boolean deletePerson(int id) { if(persons.get(id) == null) return false; persons.remove(id); return true; } @Override public Person getPerson(int id) { return persons.get(id); } @Override public Person[] getAllPersons() { Set<Integer> ids = persons.keySet(); Person[] p = new Person[ids.size()]; int i=0; for(Integer id : ids){ p[i] = persons.get(id); i++; } return p; } } |
Our web service code is ready, next steps are required to create it as a web archive that we can deploy in the servlet container.
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 |
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>JAXWS-Tomcat</display-name> <listener> <listener-class> com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener> <servlet> <servlet-name>JAXWSServlet</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>JAXWSServlet</servlet-name> <url-pattern>/personWS</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> </web-app> |
There is nothing project-specific, these are generic changes to add listener class and front servlet class for web service.
Next step is to create sun-jaxws.xml
file inside WEB-INF directory where we will provide endpoint details. URL-pattern should be same as defined in the web.xml file.
sun-jaxws.xml
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="UTF-8"?> <endpoints xmlns="https://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0"> <endpoint name="PersonServiceImpl" implementation="com.journaldev.jaxws.service.PersonServiceImpl" url-pattern="/personWS"/> </endpoints> |
That’s it, we are done. Just export project as a WAR file and deploy it into tomcat container. Access the web service URL as shown in below image.
Access the WSDL URL and take note of targetNamespace and name attributes, we will use them in the client side program.
Below is a simple test program to use our web service and run some tests.
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 |
package com.journaldev.jaxws.test; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import javax.xml.namespace.QName; import javax.xml.ws.Service; import com.journaldev.jaxws.beans.Person; import com.journaldev.jaxws.service.PersonService; public class SOAPPublisherClient { public static void main(String[] args) throws MalformedURLException { URL wsdlURL = new URL("https://localhost:8080/JAXWS-Tomcat/personWS?wsdl"); //check above URL in browser, you should see WSDL file //creating QName using targetNamespace and name QName qname = new QName("https://service.jaxws.journaldev.com/", "PersonServiceImplService"); Service service = Service.create(wsdlURL, qname); //We need to pass interface and model beans to client PersonService ps = service.getPort(PersonService.class); Person p1 = new Person(); p1.setName("Pankaj"); p1.setId(1); p1.setAge(30); Person p2 = new Person(); p2.setName("Meghna"); p2.setId(2); p2.setAge(25); //add person System.out.println("Add Person Status="+ps.addPerson(p1)); System.out.println("Add Person Status="+ps.addPerson(p2)); //get person System.out.println(ps.getPerson(1)); //get all persons System.out.println(Arrays.asList(ps.getAllPersons())); //delete person System.out.println("Delete Person Status="+ps.deletePerson(2)); //get all persons System.out.println(Arrays.asList(ps.getAllPersons())); } } |
As explained in previous tutorial, we can use wsimport utility to generate client stubs and use it. When we run above program, we get output as shown in below image.
That’s all for now, I hope you liked the tutorial and it will help you in deploying web services in Tomcat container.