Web Services

Java Web Services Tutorial

In this article, we will demonstrate examples of Java Web Services. We will provide a brief introduction to the topic, followed by a SOAP and a REST example in Java.

You can also check this tutorial in the following video:

Java Web Services Tutorial – video

1. Introduction

From W3C’s definition we are able to infer that there a web service is a piece of software that satisfies 3 key requirements :

  • The web service should be designed in such a way, that other applications can interact with it. So there should be some form of data exchange happening between that and external applications.
  • The web service should be interoperable, so it should be able to talk to applications across different platforms.
  • The communication between this web service and other applications should be facilitated over the network.

The message from an application to a web service is called a Request, and the message back to the application is called a Response. In order to ensure that the web service is interoperable, the Request and Response messages have to be specified in a universal format. The 2 common formats used for this purpose are Javascript Object Notation(JSON) and Extensible Markup Language(XML).

Every web service must provide a definition. The goals of defining a service definition are:

  1. Specify the request/response format(XML/JSON).
  2. Define the request and response structure.
  3. Define and publish the endpoint of a web service.

2. Web Service Types

There are 2 ways to implement it that are defined as follows.

2.1 SOAP

SOAP stands for Simple Object Access Protocol. In SOAP, the request and response exchange format is XML. SOAP also defines a specific request and response XML structure. The service definition in SOAP is referred to as a Web Service Definition Language(WSDL). A WSDL defines the endpoint, all operations that are allowed through it, as well as the request and response structure. The WSDL acts as a contract between the application and the web service. SOAP does not have any restrictions on the transport mechanism of the request and response messages.

2.2 REST

REST stands for Representational State Transfer. The core idea while writing a RESTful web service is to consider any data that gets exposed to an external application as a resource. Each resource is assigned a Uniform Resource Indicator(URI) that can be used to obtain data back by an application. A RESTful web service conforms to the HTTP Methods such as GET, POST, PUT and DELETE, and uses the HTTP Status Codes(200, 404, etc). There is no standard service definition language for a RESTful web service, but popular languages are Swagger and WADL.

3. Tools used

The Java examples in this article were built and run with the following tools and dependencies:

  1. Java 8
  2. Maven 3.8.0
  3. Intellij IDEA Edu 2020.1
  4. Tomcat 8.0.53
  5. Jaxws 2.3.1
  6. Jersey 2.26

4. Currency Web Service

In this article, we will illustrate a currency web service, and how this can be implemented using SOAP and REST. In this section, we will show the pom.xml, the code for the model object Currency.java and the underlying static repository class CurrencyDao.java.

4.1 Maven project

In this section, we will review the pom.xml that contains the dependencies for the SOAP and RESTful web services.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>jcg.ssowmya.demo</groupId>
    <artifactId>javaWebServices</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <tomcat.version>8.0.53</tomcat.version>
         <jersey.version>2.26</jersey.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>
        <!-- Jersey for REST web service -->
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-common</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.4.0-b180830.0438</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.inject</groupId>
            <artifactId>jersey-hk2</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <!-- Tomcat to test REST web service -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-logging-juli</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <!-- JAXWS for SOAP web service -->
        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-rt</artifactId>
            <version>2.3.1</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>rt</artifactId>
            <version>2.3.1</version>
        </dependency>
    </dependencies>
</project>

4.2 Currency class

In this section, we will review the model object that will be used for the Currency web service, namely Currency.java.

Currency.java

package jcg.ssowmya.demo.currency;

public class Currency {
    private Integer id;
    private String name;
    private String symbol;
    private String code;
    public Currency(int id, String name, String symbol, String code) {
        this.id = id;
        this.name = name;
        this.symbol = symbol;
        this.code = code;
    }
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSymbol() {
        return symbol;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
    
    @Override
    public String toString() {
        return "Currency{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", symbol='" + symbol + '\'' +
                ", code='" + code + '\'' +
                '}';
    }
}

4.3 CurrencyDao class

In this section, we will look at the repository class CurrencyDao.java that will define the different operations that will be used by the this Currency

CurrencyDao.java

package jcg.ssowmya.demo.currency;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class CurrencyDao {
    private static List currencyList = new ArrayList();
    private static int currencyCount = 0;
    static {
        currencyList.add(new Currency(1,"Indian Rupee","Rs","INR"));
        currencyList.add(new Currency(2,"American Dollar","$","USD"));
        currencyList.add(new Currency(3,"Canadian Dollar","$","CAD"));
        currencyList.add(new Currency(4, "Australian Dollar","$","AUD"));
    }
    public Currency findByCode(String code) {
        Optional currencyOptional = currencyList.stream().filter(matchId->code.equals(matchId.getCode())).findAny();
        if(currencyOptional.isPresent())
            return currencyOptional.get();
        return null;
    }
    public Currency findById(int id) {
        Optional currencyOptional = currencyList.stream().filter(matchId->matchId.getId()==id).findAny();
        if(currencyOptional.isPresent())
            return currencyOptional.get();
        return null;
    }
    public List findAll() {
        return currencyList;
    }

    public Currency save(Currency currency) {
        if(currency.getId() == null)
            currency.setId(++currencyCount);
        currencyList.add(currency);
        return currency;
    }
    public Currency deleteById(int id) {
        Optional currencyOptional = currencyList.stream().filter(matchId->matchId.getId()==id).findAny();
        if(currencyOptional.isPresent()) {
            Currency removeCurrency = currencyOptional.get();
            currencyList.remove(removeCurrency);
            return removeCurrency;
        }
        return null;
    }

}

To maintain simplicity, we are using a static list of values that will be returned as valid currencies. The CurrencyDao also has methods to find all or a specific currency, add and delete a currency.

5. SOAP Example in Java

In this section, we will implement a SOAP example in Java. The implementation makes use of Java API for XML Web Services(JAX-WS). There are 2 ways to implement a SOAP web service using JAX-WS :

  • Top-down/Contract-first: A WSDL file is first created, and the JAVA classes are generated from the WSDL.
  • Bottom-up/Contract-last: The Java classes are first written and the WSDL file is created from the classes.

We will be using the Bottom-up approach in our example, with the Currency class above as a model.

5.1 CurrencyService interface

In this section, we will implement a CurrencyService interface that will define the layout of the different operations that can be done by the web service.

CurrencyService.java

package jcg.ssowmya.demo.soapwebservices;

import javax.jws.WebMethod;
import javax.jws.WebService;
import jcg.ssowmya.demo.currency.Currency;

import java.util.List;

@WebService
public interface CurrencyService {
    @WebMethod
    public Currency getCurrencyById(int id);

    @WebMethod
    public Currency findByCode(String code);

    @WebMethod
    public List getAllCurrencies();

    @WebMethod
    public Currency save(Currency currency);

    @WebMethod
    public Currency deleteById(int id);
}

5.2 CurrencyServiceImpl class

In this section, we will write the class CurrencyServiceImpl that implements the CurrencyService interface.

CurrencyServiceImpl.java

package jcg.ssowmya.demo.soapwebservices;

import jcg.ssowmya.demo.currency.Currency;
import jcg.ssowmya.demo.currency.CurrencyDao;

import javax.jws.WebMethod;
import javax.jws.WebService;
import java.util.List;

@WebService(endpointInterface = "jcg.ssowmya.demo.soapwebservices.CurrencyService")
public class CurrencyServiceImpl implements CurrencyService{
    private static CurrencyDao currencyDao;
    static {
        currencyDao = new CurrencyDao();
    }

    @WebMethod
    public Currency getCurrencyById(int id) {
        return currencyDao.findById(id);
    }

    @WebMethod
    public Currency findByCode(String code) {
        return currencyDao.findByCode(code);
    }

    @WebMethod
    public List getAllCurrencies() {
        return currencyDao.findAll();
    }

    @WebMethod
    public Currency save(Currency currency) {
        return currencyDao.save(currency);
    }

    @WebMethod
    public Currency deleteById(int id) {
        return currencyDao.deleteById(id);
    }
}

5.3 CurrencyServicePublisher class

In this section, we will implement the class CurrencyServicePublisher to publish the endpoint and start the web service.

CurrencyServicePublisher.java

package jcg.ssowmya.demo.soapwebservices;

import javax.xml.ws.Endpoint;

public class CurrencyServicePublisher {
    public static void main(String[] args) {
        Endpoint.publish("http://localhost:8080/currencyservice", new CurrencyServiceImpl());
    }
}

In order to view the WSDL, we will need to Run the above class as a Java Application. This can be done by right-clicking the class in an IDE, and click on Run as Application. Then, when we open a browser and go to the URL http://localhost:8080/currencyservice?wsdl we will be able to see the WSDL file in an XML format.

Currency Service WSDL file

<!--  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://soapwebservices.demo.ssowmya.jcg/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://soapwebservices.demo.ssowmya.jcg/" name="CurrencyServiceImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://soapwebservices.demo.ssowmya.jcg/" schemaLocation="http://localhost:8080/currencyservice?xsd=1"/>
</xsd:schema>
</types>
<message name="getCurrencyById">
<part name="parameters" element="tns:getCurrencyById"/>
</message>
<message name="getCurrencyByIdResponse">
<part name="parameters" element="tns:getCurrencyByIdResponse"/>
</message>
<message name="findByCode">
<part name="parameters" element="tns:findByCode"/>
</message>
<message name="findByCodeResponse">
<part name="parameters" element="tns:findByCodeResponse"/>
</message>
<message name="getAllCurrencies">
<part name="parameters" element="tns:getAllCurrencies"/>
</message>
<message name="getAllCurrenciesResponse">
<part name="parameters" element="tns:getAllCurrenciesResponse"/>
</message>
<message name="deleteById">
<part name="parameters" element="tns:deleteById"/>
</message>
<message name="deleteByIdResponse">
<part name="parameters" element="tns:deleteByIdResponse"/>
</message>
<message name="save">
<part name="parameters" element="tns:save"/>
</message>
<message name="saveResponse">
<part name="parameters" element="tns:saveResponse"/>
</message>
<portType name="CurrencyService">
<operation name="getCurrencyById">
<input wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/getCurrencyByIdRequest" message="tns:getCurrencyById"/>
<output wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/getCurrencyByIdResponse" message="tns:getCurrencyByIdResponse"/>
</operation>
<operation name="findByCode">
<input wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/findByCodeRequest" message="tns:findByCode"/>
<output wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/findByCodeResponse" message="tns:findByCodeResponse"/>
</operation>
<operation name="getAllCurrencies">
<input wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/getAllCurrenciesRequest" message="tns:getAllCurrencies"/>
<output wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/getAllCurrenciesResponse" message="tns:getAllCurrenciesResponse"/>
</operation>
<operation name="deleteById">
<input wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/deleteByIdRequest" message="tns:deleteById"/>
<output wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/deleteByIdResponse" message="tns:deleteByIdResponse"/>
</operation>
<operation name="save">
<input wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/saveRequest" message="tns:save"/>
<output wsam:Action="http://soapwebservices.demo.ssowmya.jcg/CurrencyService/saveResponse" message="tns:saveResponse"/>
</operation>
</portType>
<binding name="CurrencyServiceImplPortBinding" type="tns:CurrencyService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="getCurrencyById">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="findByCode">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="getAllCurrencies">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="deleteById">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="save">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="CurrencyServiceImplService">
<port name="CurrencyServiceImplPort" binding="tns:CurrencyServiceImplPortBinding">
<soap:address location="http://localhost:8080/currencyservice"/>
</port>
</service>
</definitions>

5.4 CurrencyService Client application

In this section, we will review how to implement a client application that calls the web service we have created above. There are 2 parts to this process.

5.4.1 Generate Client artifact

The client application usually does not have access to the model objects that are used by the web service, unless these are made available in a JAR. However, in order to preserve the interoperability concept of web services, the client API is generated from the WSDL, by using the wsimport tool, which is part of the JDK package.

wsimport command line tool

wsimport -keep -p jcg.ssowmya.demo.jaxws.client http://localhost:8080/currencyservice?wsdl

In the above command, the -p is used to specify the target location for the generated Java files. After running this command from the source folder of the project, we will see a number of Java classes generated under the package jcg.ssowmya.demo.jaxws.client.

5.4.2 CurrencyServiceClient class

Now that we have a local copy of the API, we will see how to write the client application that invokes to retrieve data.

CurrencyServiceClient.java

package jcg.ssowmya.demo.soapwebservices.client;

import src.main.java.jcg.ssowmya.demo.jaxws.client.Currency;
import src.main.java.jcg.ssowmya.demo.jaxws.client.CurrencyService;
import src.main.java.jcg.ssowmya.demo.jaxws.client.CurrencyServiceImplService;

import java.net.URL;
import java.util.List;

public class CurrencyServiceClient {
    public static void main(String[] args) throws Exception{
        URL url = new URL("http://localhost:8080/currencyservice?wsdl");
        CurrencyServiceImplService currencyServiceImplService = new CurrencyServiceImplService(url);
        CurrencyService currencyService = currencyServiceImplService.getCurrencyServiceImplPort();
        List currencyList = currencyService.getAllCurrencies();
        System.out.println("Number of currencies retrieved: "+currencyList.size());
    }
}

6. REST Example in Java

In this section, we will show how to write a simple RESTful web service. The base model class for the REST Example will be Currency.java, and the repository class will be CurrencyDao.java that have been shown above. Further, the REST web service will make use of the Jersey dependency specified in the pom.xml code above.

6.1 CurrencyResource class

For this the key idea is to view every base model object as a resource, and to get specific data from the resource, we will be using a Uniform Resource Identifier(URI). Let us look at an implementation of the CurrencyResource class.

CurrencyResource.java

package jcg.ssowmya.demo.restfulwebservices;

import jcg.ssowmya.demo.currency.Currency;
import jcg.ssowmya.demo.currency.CurrencyDao;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path("/CurrencyService")
public class CurrencyResource {
    private CurrencyDao currencyDao = new CurrencyDao();
    @GET
    @Path("/hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String helloWorld() {
        return "Hello!";
    }

    @GET
    @Path("/currency")
    @Produces(MediaType.APPLICATION_JSON)
    public List getAllCurrency() {
        return currencyDao.findAll();
    }
}

From the above code, we see that we will need to use the path /CurrencyService/currency to retrieve the list of all currencies in JSON format.

6.2 Web.xml

The RESTful web service will need to be deployed as a web application on a local Tomcat server, and hence we will need to write a web.xml as follows:

web.xml

<?xml version = "1.0" encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xmlns = "http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id = "javaWebServices" version = "3.0">
    <display-name>Java Restful Web Services</display-name>
    <servlet>
        <servlet-name>Currency RESTful Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>jcg.ssowmya.demo.restfulwebservices</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Currency RESTful Application</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

6.3 CurrencyResourceApplication class

There are 2 ways to run the RESTful web service. If we have a local Tomcat server, then we just need to deploy it. If we do not have a locally installed Tomcat, then the class below will start an embedded Tomcat Server that will be used to deploy the web service.

CurrencyResourceApplication

package jcg.ssowmya.demo.restfulwebservices;

import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.glassfish.jersey.servlet.ServletContainer;

import java.io.File;

public class CurrencyResourceApplication {
    public static void main(String[] args) throws Exception {
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8082);
        tomcat.setBaseDir("tmp");
        String webAppDirLocation ="src/main/resources/webapp/";
        Context context = tomcat.addWebapp("/restfulws", new File(webAppDirLocation).getAbsolutePath());
        File configFile = new File(webAppDirLocation+"WEB-INF/web.xml");
        context.setConfigFile(configFile.toURI().toURL());
        tomcat.start();
        tomcat.getServer().await();
    }
}

In our IDE, we can right click on this class and select “Run as Application“. This will start an embedded Tomcat server on port 8082. Then, we can open any browser and type the URL http://localhost:8082/restfulws/CurrencyService/currency. This will result in the following JSON output in our browser:

Browser output for /CurrencyService/currency

[{"id":1,"name":"Indian Rupee","symbol":"Rs","code":"INR"},{"id":2,"name":"American Dollar","symbol":"$","code":"USD"},{"id":3,"name":"Canadian Dollar","symbol":"$","code":"CAD"},{"id":4,"name":"Australian Dollar","symbol":"$","code":"AUD"}]

7. Summary

In this article, we saw 2 different implementations of Java Web Services, using SOAP and REST. We were able to highlight the differences in implementations between the two, as well as the formats of the request and response messages in each case.

8. Download the Source Code

Download
You can download the full source code of this example here: Java Web Services Tutorial

Sowmya Shankar

Sowmya works as a Senior Web Applications Programmer in the higher educational sector, where she leads projects based on Java. She graduated from Anna University's Computer Sciences department, followed by a Masters degree in Computer and Information Sciences from the University of Delaware. Her project portfolio features diverse web applications using frameworks such as Struts2, Spring, Spring Boot, as well as her recent experiments in the world of Microservices and the React JS framework.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button