Creating a SOAP Web Service in Java with Eclipse IDE and Tomcat

In this example, the Eclipse Java EE IDE is used to create a new SOAP 1.1 web service. The Apache Tomcat web server is used to deploy and run the web service and SOAP-UI is used to test the service operations. The SOAP 1.1 web service in this example represents a simple product catalog and provides methods to search and insert products.

Related Posts

Summary

  1. Installation of Eclipse Java EE IDE
  2. Installation of Apache Tomcat 7 Web Server
  3. Configuration of Tomcat 7 Runtime Environment in Eclipse
  4. Setup of new Dynamic Web Project in Eclipse
  5. Setup of Service Implementation Java Class
  6. Setup of new SOAP 1.1 Web Service in Eclipse
  7. Testing the new SOAP Web Service with SOAP UI
  8. Creating a WAR File for Deployment of the SOAP Service

Software Downloads

The open-source software used in this example can be downloaded from these sources:

Java Runtime Environment from Oracle (e.g version 8, update 111)
Apache Tomcat Web Server (here version 7)
Eclipse Java EE IDE from the Eclipse Downloads page (here Kepler SR2)
SOAP-UI from the SOAP-UI open source downloads

Eclipse Java EE IDE for Web Developers - About

  • The Eclipse IDE is packaged as a ZIP file. After downloading the file, unzip it to a folder on your hard drive.

Eclipse Java EE IDE for Web Developers - ZIP file

  • In this case, Eclipse is installed in: C:\eclipse-jee-kepler.
  • After unzipping the file, the folder should contain the files shown below.
Note: Make sure that you have a Java Runtime Environment (JRE) installed before trying to run Eclipse.

Eclipse Java EE IDE for Web Developers - root folder

  • Run Eclipse by clicking on the application icon as shown in the screen shot.

  • Visit https://tomcat.apache.org/index.html and download the Apache Tomcat Web Server. For this example, version 7 was used.
  • It is recommended to download the binary distribution for your operating system (e.g. Windows 7 32-bit), which provides a ZIP file.
  • Unzip the downloaded file to a folder on your hard drive, for example to C:\tomcat7. The Tomcat 7 root folder should look like this:

Apache Tomcat 7 - Root folder

  • Start the Eclipse IDE by clicking on the Eclipse application icon shown earlier.
  • In Eclipse, navigate to: Window > Preferences.

Eclipse Java EE IDE for Web Developers - Preferences

  • In the Preferences dialog window, extend the Server node and click on Runtime Environments.
  • Then click on the Add… button to add a new runtime environment.

Eclipse Java EE IDE for Web Developers - Server Runtime Environments

  • In the New Server Runtime Environment dialog, select Apache Tomcat v7.0 and click on Next.

Eclipse Java EE IDE for Web Developers - New Server Runtime Environment

  • On the following screen, use the Browse… button to select the root folder of the Tomcat web server.
  • This is the folder into which the Tomcat ZIP file was unzipped. It contains the bin folder.

Eclipse Java EE IDE for Web Developers - Select Tomcat Installation Directory

  • Click on Finish to complete the runtime environment setup. The Apache Tomcat v7.0 web server should now be listed in the Server Runtime Environments screen.

Eclipse Java EE IDE for Web Developers - Available Server Runtime Environments

  • Click on OK to close the runtime environment setup.

  • In the Eclipse IDE, navigate to the main menu and click on File > New > Dynamic Web Project.
  • In the configuration screen, enter the project name and select the target runtime.
  • In this case, the target runtime will be the previously configured Apache Tomcat v7.0 web server.
  • Click on Finish to complete the setup.

Eclipse - New Dynamic Web Project

  • The new dynamic web project should now show up in the Project Explorer in the Eclipse IDE as shown below:

Eclipse Java EE IDE for Web Developers - Project Explorer with Dynamic Web Project

  • Right click on the project name and select New > Class in the context menu to create a new Java class that will serve as the implementation class for the web service.

Eclipse Java EE IDE for Web Developers - Create a new Java Class

  • Select an appropriate package name and complete the name of the class. Then click on Finish and open the class in the Java editor.
  • For this example, the ProductCatalogServiceImpl Java class provides 3 methods and maintains a simple product catalog as an in-memory list:
package com.pegaxchange.services;

import java.util.*;

public class ProductCatalogServiceImpl {

    private static List<Product> productCatalog;

    public ProductCatalogServiceImpl() {
        initializeProductCatalog();
    }

    public Product searchById(int id) throws Exception {
        for (Product p : productCatalog) if (p.getId() == id) return p;
        throw new Exception("No product found with id " + id);
    }

    public Product[] getAllProducts() {
        Product[] products = new Product[productCatalog.size()];
        int i = 0;
        
        for (Product p : productCatalog) {
            products[i] = p;
            i++;
        }
        
        return products;
    }
    
    public void insertProduct(Product product) {
        productCatalog.add(product);
    }

    private void initializeProductCatalog() {

        if (productCatalog == null) {
          productCatalog = new ArrayList();
          productCatalog.add(new Product(1, "Keyboard", "Electronics", 29.99D));
          productCatalog.add(new Product(2, "Mouse", "Electronics", 9.95D));
          productCatalog.add(new Product(3, "17\" Monitor", "Electronics", 159.49D));
          productCatalog.add(new Product(4, "Hammer", "Hardware", 9.95D));
          productCatalog.add(new Product(5, "Slot Screwdriver", "Hardware", 7.95D));
          productCatalog.add(new Product(6, "The British Invasion of Java", "Books", 11.39D));
          productCatalog.add(new Product(7, "A House in Bali", "Books", 15.99D));
          productCatalog.add(new Product(8, "An Alaskan Odyssey", "Books", 799.99D));
          productCatalog.add(new Product(9, "LCD Projector", "Electronics", 1199.19D));
        }
    }
}

The 3 public methods in the class are:

  • searchById – Returns the product with the given id
  • getAllProducts – Returns a list of all products
  • insertProduct – Adds a new product to the product catalog list object

Note: The initializeProductCatalog method is called in the constructor and creates an in-memory ArrayList of Product objects. In reality, the product catalog would be backed by a database or some other system of record. In addition, a Java bean class that represents a product in the catalog was created:

package com.pegaxchange.services;

public class Product {

    private int id;
    private String name;
    private String category;
    private double unitPrice;

    public Product() {}

    public Product(int id, String name, String category, double unitPrice) {
        this.id = id;
        this.name = name;
        this.category = category;
        this.unitPrice = unitPrice;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public double getUnitPrice() {
        return unitPrice;
    }

    public void setUnitPrice(double unitPrice) {
        this.unitPrice = unitPrice;
    }
}

  • In the Eclipse main menu, click on File > New > Other.
  • In the Wizard dialog, expand the Web Services node, select Web Service and click on Next.

Eclipse Java EE IDE for Web Developers - New Web Service Wizard

  • On the Web Services wizard screen, select Bottom up Java bean Web Service for the web service type and use the Browse button to select the service implementation class.
  • In this case it is the com.pegaxchange.services.ProductCatalogServiceImpl Java class created in step 5.
  • In the configuration section, leave the slider at the Start level. This will configure Eclipse to automatically deploy and start the web service on the Apache Tomcat v7 runtime.
  • Omit the client configuration for now and make sure the option Publish the Web service is checked. Click on Next to continue.

Note: Under Configuration:, the entry Web service runtime: Apache Axis refers to Axis version 1.4 which generates SOAP version 1.1 web services.

Eclipse Java EE IDE for Web Developers - New Web Service Configuration

  • The next screen lists the name of the WSDL file that will be created and the public methods available in the service implementation class that can be exposed through the SOAP web service.
  • The document type can be set on this screen as well.

Eclipse Java EE IDE for Web Developers - Web Service Java Bean Identity

  • Click on Next to continue. The Eclipse IDE will now generate the web service files. If the Apache Tomcat web server is NOT running at this point, the following Server startup screen will be shown:

Eclipse Java EE IDE for Web Developers - Tomcat Server Startup

  • Click on the Start server button to start the web server and then click on the Next button and after the service has been deployed, click on the Finish button to close the Web Service wizard.
  • The service should now be up and running on the local Tomcat web server as shown below.

Eclipse Java EE IDE for Web Developers - Tomcat v7.0 Server at localhost running

  • Confirm that the WSDL file is accessible by navigating to the following URL in a web browser:
https://localhost:8080/ProductCatalogSOAPService/services/ProductCatalogServiceImpl?wsdl

Product Catalog SOAP Web Service - Access WSDL via URL

  • Note that the namespace of the generated WSDL is https://schemas.xmlsoap.org/wsdl/soap, which indicates a SOAP 1.1 compliant web service.
  • For more information on SOAP 1.1 vs. 1.2 see this post on W3C.
  • For completeness, here is the entire WSDL file for the ProductCatalogSOAPService that was generated by Eclipse:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="https://services.pegaxchange.com" 
    xmlns:apachesoap="https://xml.apache.org/xml-soap" 
    xmlns:impl="https://services.pegaxchange.com" 
    xmlns:intf="https://services.pegaxchange.com" 
    xmlns:wsdl="https://schemas.xmlsoap.org/wsdl/" 
    xmlns:wsdlsoap="https://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:xsd="https://www.w3.org/2001/XMLSchema">
  <!--WSDL created by Apache Axis version: 1.4 Built on Apr 22, 2006 (06:55:48 PDT)-->
  <wsdl:types>
    <schema elementFormDefault="qualified" 
        targetNamespace="https://services.pegaxchange.com" 
        xmlns="https://www.w3.org/2001/XMLSchema">
      <element name="searchById">
        <complexType>
          <sequence>
            <element name="id" type="xsd:int"/>
          </sequence>
        </complexType>
      </element>
      <element name="searchByIdResponse">
        <complexType>
          <sequence>
            <element name="searchByIdReturn" type="impl:Product"/>
          </sequence>
        </complexType>
      </element>
      <complexType name="Product">
        <sequence>
          <element name="category" nillable="true" type="xsd:string"/>
          <element name="id" type="xsd:int"/>
          <element name="name" nillable="true" type="xsd:string"/>
          <element name="unitPrice" type="xsd:double"/>
        </sequence>
      </complexType>
      <element name="insertProduct">
        <complexType>
          <sequence>
            <element name="product" type="impl:Product"/>
          </sequence>
        </complexType>
      </element>
      <element name="insertProductResponse">
        <complexType/>
      </element>
      <element name="getAllProducts">
        <complexType/>
      </element>
      <element name="getAllProductsResponse">
        <complexType>
          <sequence>
            <element maxOccurs="unbounded" name="getAllProductsReturn" type="impl:Product"/>
          </sequence>
        </complexType>
      </element>
    </schema>
  </wsdl:types>
  <wsdl:message name="insertProductResponse">
    <wsdl:part element="impl:insertProductResponse" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="getAllProductsRequest">
    <wsdl:part element="impl:getAllProducts" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="searchByIdRequest">
    <wsdl:part element="impl:searchById" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="getAllProductsResponse">
    <wsdl:part element="impl:getAllProductsResponse" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="searchByIdResponse">
    <wsdl:part element="impl:searchByIdResponse" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="insertProductRequest">
    <wsdl:part element="impl:insertProduct" name="parameters"/>
  </wsdl:message>
  <wsdl:portType name="ProductCatalogServiceImpl">
    <wsdl:operation name="searchById">
      <wsdl:input message="impl:searchByIdRequest" name="searchByIdRequest"/>
      <wsdl:output message="impl:searchByIdResponse" name="searchByIdResponse">
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="insertProduct">
      <wsdl:input message="impl:insertProductRequest" name="insertProductRequest"/>
      <wsdl:output message="impl:insertProductResponse" name="insertProductResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getAllProducts">
      <wsdl:input message="impl:getAllProductsRequest" name="getAllProductsRequest"/>
      <wsdl:output message="impl:getAllProductsResponse" name="getAllProductsResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="ProductCatalogServiceImplSoapBinding" type="impl:ProductCatalogServiceImpl">
    <wsdlsoap:binding style="document" transport="https://schemas.xmlsoap.org/soap/https"/>
    <wsdl:operation name="searchById">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="searchByIdRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="searchByIdResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="insertProduct">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="insertProductRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="insertProductResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="getAllProducts">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getAllProductsRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getAllProductsResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="ProductCatalogServiceImplService">
    <wsdl:port binding="impl:ProductCatalogServiceImplSoapBinding" 
         name="ProductCatalogServiceImpl">
      <wsdlsoap:address 
         location="https://prpc:8080/ProductCatalogSOAP11/services/ProductCatalogServiceImpl"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

There are many options for testing a SOAP web service, including generating a test client in Eclipse. In this example, a free external tool called SOAP-UI is used to test the web service operations.

Note: Make sure that the Tomcat web server is running at this point and that the web service is deployed as described in step 6, where the service’s WSDL file is accessed in a browser.

SOAP UI - New SOAP Project

  • A new dialog window prompts for the project name and the WSDL file.
  • In this case, the URL shown earlier is copied into the Initial WSDL field:
https://localhost:8080/ProductCatalogSOAPService/services/ProductCatalogServiceImpl?wsdl
  • Check the ckeckbox Create sample requests for all operations? is checked and click on OK.

SOAP-UI - New SOAP Project from WSDL

  • SOAP-UI will automatically download the WSDL, process it and create request stubs for each service operation.
  • In order to call one of the operations of the web service, double click on the Request 1 item under that operation.
  • Then click on the green triangle inside the request window to run the request.
  • E.g.: calling the operation getAllProducts results in the following request and response XML.

SOAP UI - Execute Sample request getAllProducts

  • Similarly, calling the operation insertProduct results in the following request and response XML.

SOAP UI - Execute Sample request insertProduct

  • Calling the operation searchByID results in the following request and response XML.

SOAP UI - Execute Sample request searchById

  • A WAR file (Web Archive) can be created by exporting the dynamic web project in Eclipse.
  • The WAR file is used to deploy the SOAP web service to a Jave EE compliant application server.
  • In the Eclipse IDE, in the Project Explorer, right click on the node for the dynamic web project
  • Select Export > WAR file to launch the WAR Export dialog.

Eclipse IDE - Project Explorer - Export Dynamic Web Project as WAR file

  • In the WAR Export dialog, select the Destination using the Browse button and then click on Finish to complete the WAR export.

Eclipse IDE - Project Explorer - Export Dynamic Web Project as WAR file - Select Destination Directory

  • The generated WAR file will be copied into the specified destination directory:

Eclipse IDE - Generated WAR file

18 thoughts on “Creating a SOAP Web Service in Java with Eclipse IDE and Tomcat

  1. Hi Bruno,
    Thanks for the post but getting a “Type mismatch: cannot convert from element type Object to Product” at the line :

    for (Product p : productCatalog) if (p.getId() == id) return p;

    in the ProductCatalogSOAPImpl.java.
    Any help is appreciated.

    Thanks

  2. Hii .. Thank you very much for creating such a valuable blog…Please keep on adding new articles … If possible can you create new post on – Creating REST service in Pega 7 and accessing it from external application-Java. Thanks.

  3. Hi!

    Everything from this tutorial worked just fine for me. But when I try to make requests from a Python Script instead of SOAP UI, I get an error message. How can I fix it?

    The python script:
    import requests

    url=”http://localhost:8088/ProductCatalogSOAPService/services/ProductCatalogServiceImpl”
    #headers = {‘content-type’:’application/soap+xml’}
    headers = {‘content-type’: ‘text/xml’}
    body = “””

    “””

    response = requests.post(url,data=body,headers=headers)

    print response
    print response.content

    The response:

    ns1:Client.NoSOAPAction
    no SOAPAction header!

    Marcuss-MacBook-Pro.local

Leave a Reply