Example of How to Create a TCP/IP Server Socket and Client Socket in Java

In this example, Java is used to create a new TCP/IP based server and client socket application. Here, Java SE 8 and the setup in the post below was used. If needed, read it first to setup your Java IDE with Eclipse..

The Java APIs for socket programming are part of the Java SE (Standard Edition). See java.io and java.net.

Summary

  1. Implementation of Server Socket in Java
  2. Implementation of Client Socket in Java
  3. Running the Server Socket and Client Socket
  4. Monitoring TCP/IP Network Traffic using Wireshark

  • Below is the Java source code for the server socket implementation.
  • The server socket is created in line 14. See java.net.ServerSocket for more information.
package com.pgx.java.socket;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServerSocket {

    private ServerSocket server;

    public MyServerSocket(String bindAddr) throws Exception {
        this.server = new ServerSocket(0, 1, InetAddress.getByName(bindAddr));
    }

    private void listen() throws Exception {
        String data = null;
        Socket client = this.server.accept();
        String clientAddress = client.getInetAddress().getHostAddress();
        System.out.println("\r\nNew connection from " + clientAddress);
        
        BufferedReader in = new BufferedReader(
                new InputStreamReader(client.getInputStream()));        

        while ( (data = in.readLine()) != null ) {
            System.out.println("\r\nMessage from " + clientAddress + ": " + data);
        }
    }

    public InetAddress getSocketAddress() {
        return this.server.getInetAddress();
    }
    
    public int getPort() {
        return this.server.getLocalPort();
    }

    public static void main(String[] args) throws Exception {
        MyServerSocket app = new MyServerSocket(args[0]);
        
        System.out.println("\r\nRunning Server: " + 
                "Host=" + app.getSocketAddress().getHostAddress() + 
                " Port=" + app.getPort());
        
        app.listen();
    }
}

The main methods in this class:

  • Requires one input argument, the host name to use.
  • This can be an IP address or a host name string.
  • The port to listen on will be automatically selected.

  • Below is the Java source code for the client socket implementation.
  • The server socket is created in line 15. See java.net.Socket for more information.
package com.pgx.java.socket;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

public class MyClientSocket {

    private Socket socket;
    private Scanner scanner;

    private MyClientSocket(InetAddress serverAddress, int serverPort) throws Exception {
        this.socket = new Socket(serverAddress, serverPort);
        this.scanner = new Scanner(System.in);
    }

    public static void main(String[] args) throws Exception {                       
        MyClientSocket client = new MyClientSocket(
                InetAddress.getByName(args[0]), 
                Integer.parseInt(args[1]));
        
        System.out.println("\r\nConnected to: " + client.socket.getInetAddress());
        client.start();             
    }

    private void start() throws IOException {
        String input;

        while (true) {
            input = scanner.nextLine();

            PrintWriter out = new PrintWriter(this.socket.getOutputStream(), true);
            out.println(input);
            out.flush();
        }
    }   
}

  • Here, the application was exported to an executable JAR file named TCPSocketTest.jar.
  • The server- and client socket will be run on the same machine with IP address 192.168.0.15.

3.1 Start the Server

  • To run the server socket from a terminal or Windows command prompt, use the java command:
  java -cp TCPSocketTest.jar com.pgx.java.socket.MyServerSocket 192.168.0.15
  • Where the first input argument is the server name or IP address, here 192.168.0.15.
  • When the server socket is running, it will print the host name and the socket port.

MyMac:Java root$ ls
TCPSocketTest.jar
MyMac:Java root$ java -cp TCPSocketTest.jar com.pgx.java.socket.MyServerSocket 192.168.0.15

Running Server: Host=192.168.0.15 Port=53257
 
  • The socket port, here 53257, is set automatically. See line 14 in the MyServerSocket code and java.net.ServerSocket for more information.
  • The server socket is now ready to accept client connections.

3.2 Start the Client

  • To run the client socket from a terminal or Windows command prompt, use the java command:
  java -cp TCPSocketTest.jar com.pgx.java.socket.MyClientSocket 192.168.0.15 53257

MyMac:Java root$ ls
TCPSocketTest.jar
MyMac:Java root$ java -cp TCPSocketTest.jar com.pgx.java.socket.MyClientSocket 192.168.0.15 53257

Connected to: /192.168.0.15
 
  • The server socket application will print a message indicating that a client connection was established.

3.3 Send a Message

  • In the client socket application, type a message and press ENTER.

MyMac:Java root$ ls
TCPSocketTest.jar
MyMac:Java root$ java -cp TCPSocketTest.jar com.pgx.java.socket.MyClientSocket 192.168.0.15 53257

Connected to: /192.168.0.15
Hello from the client!

  • The server socket application, will print the message that was received from the client.

MyMac:Java root$ ls
TCPSocketTest.jar
MyMac:Java root$ java -cp TCPSocketTest.jar com.pgx.java.socket.MyServerSocket 192.168.0.15

Running Server: Host=192.168.0.15 Port=53257

Message from 192.168.0.15: Hello from the client!
 
  • The Java server and client applications can be stopped by pressing CTRL + C.

Wireshark - Download Website

  • After installation, run Wireshark and select a network interface to capture traffic on.
  • Here, the localhost’s Loopback interface lo0 is selected to monitor local traffic.

Wireshark - Select Network Interface for Network Traffic Capture

  • In the green filter field, enter the below pattern to filter the traffic by the server socket TCP port:
tcp.port == 53257
  • Send messages from the client- to the server socket to capture traffic.
  • To view the payload of a TCP packet, expand the Data node and click on the [Length: ..] item.

Wireshark - TCP Traffic Capture on Loopback Interface

How to Setup Maven 3.5 on macOS 10 and Create a Java Project from Archetype

  • This post shows how to setup Maven and how to create, build and run a new Maven Java project on macOS 10.
  • Before continuing, make sure that a Java SDK 1.7 or greater is installed and that the commands are available in your PATH environment variable. In a terminal window, run the following command to confirm this:
java -version

MacBookPro:opt admin$ java -version
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)
MacBookPro:opt admin$
 
  • For a related post on installing a Java SDK and seting up a Java EE development environment refer to the below post on this site:

Summary

  1. Installing and Configuring Maven 3.5 on macOS 10
  2. Creating a Maven Java Project from an Archetype
  3. Adding Project Dependencies in the POM File
  4. Execute the Java Application with the Maven exec Plugin

  • In this example, Maven 3.5 is used. It can be downloaded as a binary distribution from the Apache Maven Website.

Download Maven Binary Distribution from Apache Maven Website

  • Unzip the Maven 3.5 files into some folder on the local disk. In this example, the Maven files are unzipped into the ${maven.home} folder at:
/opt/apache-maven-3.5.0

Maven Home Folder Contents

  • For instructions on how to add the Maven commands from the ${maven.home}\bin folder to the PATH environment variable on macOS see:
  • Open a terminal window and verify that maven is installed properly by executing the below command to view the Maven version:
mvn -version
  • The output should look like the example below, showing the Java version and Java home folder:

Last login: Wed Oct 11 01:07:07 on ttys000
MacBookPro:~ admin$ /opt/apache-maven-3.5.0/bin/mvn -version
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-03T15:39:06-04:00)
Maven home: /opt/apache-maven-3.5.0
Java version: 1.8.0_77, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.12.5", arch: "x86_64", family: "mac"
MacBookPro:~ admin$

  • If a proxy is needed to connect to the Internet, edit ${maven.home}/.m2/conf/settings.xml:
  <!-- proxies
   | This is a list of proxies which can be used on this machine to connect to the network.
   | Unless otherwise specified (by system property or command-line switch), the first proxy
   | specification in this list marked as active will be used.
   |-->
  <proxies>
    <!-- proxy
     | Specification for one proxy, to be used in connecting to the network.
     |-->
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>domain\username</username>
      <password>password</password>
      <host>proxy.host.com</host>
      <port>80</port>
      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
    </proxy>
  </proxies>
  • When a Maven project is built, Maven will download all dependent artifacts (JAR files) from a remote repository to a local repository. By default, Maven will create the local repository in:
${user.home}/.m2/repository
  • The Maven local repository contains all downloaded artifacts and looks like the example below:

Default Maven Local Repository Location on macOS

  • To change the location of the local repository, edit ${maven.home}/.m2/conf/settings.xml:
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   | Default: ${user.home}/.m2/repository
   |-->
  <localRepository>/my/local/repository</localRepository>

  • To create a Maven Java project with JUnit support, using the archetype maven-archetype-quickstart, execute the command:
mvn archetype:generate -DgroupId=com.company.app -DartifactId=my-app 
    -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
  • When Maven first downloads required dependencies to the local repository, the build may take a while.
  • The output should look like below and result in a BUILD SUCCESS message.
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/archetype/maven-archetype-parent/1/maven-archetype-parent-1.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/archetype/maven-archetype-parent/1/maven-archetype-parent-1.pom (1.3 kB at 8.7 kB/s)
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/4/maven-parent-4.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/4/maven-parent-4.pom (10.0 kB at 54 kB/s)
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar (4.3 kB at 28 kB/s)
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /Users/admin/Desktop/MyProjects/pegaxchange.com/posts/3506
[INFO] Parameter: package, Value: com.company.app
[INFO] Parameter: groupId, Value: com.company.app
[INFO] Parameter: artifactId, Value: my-app
[INFO] Parameter: packageName, Value: com.company.app
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /Users/admin/Desktop/MyProjects/pegaxchange.com/posts/3506/my-app
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.639 s
[INFO] Finished at: 2017-10-18T18:07:10-04:00
[INFO] Final Memory: 19M/308M
[INFO] ------------------------------------------------------------------------
MacBookPro:3506 admin$ 
  • Maven will create a folder using the artifactId and create the standard project structure based on the groupId:
my-app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- company
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- company
                    `-- app
                        `-- AppTest.java
  • The root folder of the Maven project contains a POM file (Project Object Model). Here, the file contains:
<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/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.company.app</groupId>
    <artifactId>my-app</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>my-app</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
  • To compile and package the Java project, execute in the project root folder (containing the pom.xml file):
mvn clean compile package
[INFO] Compiling 1 source file to /Users/admin/my-app/target/test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ my-app ---
[INFO] Surefire report directory: /Users/admin/my-app/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.company.app.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.005 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ my-app ---
[INFO] Building jar: /Users/admin/my-app/target/my-app-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.568 s
[INFO] Finished at: 2017-10-18T19:12:04-04:00
[INFO] Final Memory: 16M/186M
[INFO] ------------------------------------------------------------------------
MacBookPro:my-app admin$
  • The resulting JAR file is located in the target folder of the project:

Maven Java Standard Project Structure

  • It can be executed from the project folder with the java command:
java -cp target/my-app-1.0-SNAPSHOT.jar com.company.app.App
  • Which will produce the below output:
MacBookPro:my-app admin$ java -cp target/my-app-1.0-SNAPSHOT.jar com.company.app.App
Hello World!
MacBookPro:my-app admin$ 
  • As per the App.java source file:
package com.company.app;

public class App {

    public static void main( String[] args ) {
        System.out.println( "Hello World!" );
    }
}

  • The Maven Central Repository is used to find and add dependencies to a project’s POM file.
  • For example, to add support for JSON processing to the project, Google’s GSON API can be used.
  • Search for "GSON" in the Maven Central Repository to find the Maven dependency information.

Maven Central Repository - Search for Artifact

  • Click on the version link, here 2.8.2, to view the dependency information:

Maven Central Repository - GSON 2.8.2 Artifact Details

  • Copy and paste the dependency information from the Apache Maven section into the project’s POM file:
<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/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.company.app</groupId>
    <artifactId>my-app</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>my-app</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- Support for JSON Processing -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
        </dependency>
    </dependencies>
</project>
  • The scope of the new dependency is not specified. It is compile by default. See Dependency Scope for more information.
  • The GSON API can now be used in the App.java source file to serialize Java objects:
package com.company.app;

import com.google.gson.Gson;

public class App {

    public static void main( String[] args ) {
        Car car = new App().new Car();
        car.setMake("BMW");
        car.setModel("335i");

        System.out.println(new Gson().toJson(car));
    }

    class Car {

        private String make;
        private String model;

        public String getMake() {
            return make;
        }

        public void setMake(String make) {
            this.make = make;
        }

        public void setModel(String model) {
            this.model = model;
        }

        public String getModel() {
            return model;
        }
    }
}

  • Maven can be used to compile and then execute the App class using the exec plugin:
mvn compile exec:java -Dexec.mainClass="com.company.app.App"
  • The output will be a JSON representation of the Car object:
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ my-app ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/admin/my-app/target/classes
[INFO] 
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ my-app ---
{"make":"BMW","model":"335i"}
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.421 s
[INFO] Finished at: 2017-10-19T12:52:29-04:00
[INFO] Final Memory: 18M/301M
[INFO] ------------------------------------------------------------------------
{"make":"BMW","model":"335i"}

Setup of Java EE Development Environment with Eclipse Neon and Tomcat 9

In this example, the Eclipse Java EE IDE (Java Enterprise Edition – Integrated Development Environment) and the Apache Tomcat Web Server are used to setup and configure a Java EE development environment for developing and testing Java web applications. This setup allows Java developers to create web applications that contain Java Servlets, JavaServer Pages and REST- & SOAP web services.

Related Posts

Summary

  1. Installation of Java Runtime Environment
  2. Installation of Apache Tomcat Web Server
  3. Installation of Eclipse IDE for Java EE Developers
  4. Setup of Tomcat Runtime Environment in Eclipse
  5. Setup of new Dynamic Web Project in Eclipse
  6. Creation of "Hello World" Servlet and JSP View
  7. Run the Dynamic Web Project in Eclipse
  8. Export as WAR File and Deployment to Tomcat

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 9)
Eclipse Java EE IDE from the Eclipse Downloads page (e.g Neon 1A)

  • Download the latest Java Runtime Environment for your operating system. I used JRE version 8, update 111 (released: October 18, 2016) for this post.

Oracle Java JRE Version 8 Download Page

  • Install the JRE by following the installation instructions.

Oracle Java JRE Version 8 Installation on Windows

  • Confirm JRE installation by opening a command prompt and executing java -version
  • Confirm the JAVA_HOME environment variable setting by executing  set JAVA_HOME

Oracle Java JRE 8 Check Java Version and Java Home on Windows 7 Command Line

  • The Java Runtime Environment is now installed.

  • Download the Apache Tomcat web server. In this example, the binary distribution of version 9 for Windows 64-bit was used.

Apache Tomcat 9 Download Page

Note: If Tomcat is installed as a Windows service, some steps in this section will be different.
  • Install the Tomcat web server by un-zipping the downloaded ZIP file to any location. Here, c:\tomcat9 was used as the root folder.

Apache Tomcat 9 ZIP File for Windows x64

  • Validate the Tomcat installation by navigating to the root folder and starting the web server by executing bin\startup.bat

Apache Tomcat 9 bin folder and startup.bat file

  • On Windows, a new CLI window will open, showing the Tomcat console output. A message saying Server startup in XXXX ms indicates that the web server started successfully.

Apache Tomcat 9 Startup Console Output on Windows 7 Command Line

  • Access the Tomcat welcome page using http://localhost:8080 in a web browser to confirm that the Tomcat Server is running properly.

Apache Tomcat 9.0.0 M11 Welcome Page

  • Shutdown Tomcat by executing the file bin\shutdown.bat located in the root folder.

Apache Tomcat 9 bin folder shutdown.bat Windows 7

  • Download the latest Eclipse Java EE IDE for your operating system. For example, for Eclipse Neon 1A on 64-bit Windows 7, go to the Eclipse Neon website and use the Windows 64-bit link.

Eclipse IDE for Java EE Developers - Download Page - Neon Package

  • Install the Eclipse Java EE IDE by unzipping the downloaded ZIP file into any location. Here, c:\eclipse-neon-ide was used as the root folder.

Eclipse IDE for Java EE Developers - ZIP File for Windows 64-bit

  • Start the Eclipse IDE by navigating to the root folder and executing eclipse.exe

Eclipse IDE for Java EE Developers - Startup with Eclipse.exe on Windows 7 64-bit

  • When starting Eclipse for the first time, it may be necessary to set the default workspace. Select any location and check the checkbox Use this as the default and do not ask again.

Eclipse IDE for Java EE Developers - Initial Start - Select Workspace

  • Click on OK to launch Eclipse and view the default Welcome page.

  • At the initial launch, Eclipse will show the Welcome page. Before clicking on any of the links, it is recommended to setup the Apache Tomcat 9 web server runtime environment in Eclipse.
  • This allows a developer to run and debug dynamic web projects on Tomcat from within Eclipse.
  • To setup a new runtime environments, navigate to Window > Preferences.

Eclipse IDE for Java EE Developers - Menu > Window > Preferences

  • In the Preferences dialog, select Server > Runtime Environments and then click on the Add… button to setup a new runtime environment.

Eclipse IDE for Java EE Developers - Preferences > Server Runtime Environments > Add

  • In the New Server Runtime Environment dialog, select Apache Tomcat v9.0 from the list and then click on the Next button.

Eclipse IDE for Java EE Developers - Preferences > Server Runtime Environments > New Server Runtime Environment

  • Specify the installation directory of Tomcat by clicking on Browse and selecting the root folder of the Tomcat installation. In this example c:\tomcat9 was used as the root folder.
  • Click on Finish to continue.

Eclipse IDE for Java EE Developers - Preferences > Server Runtime Environments > New Tomcat Server Runtime Environment

  • The Apache Tomcat v9.0 web server is now available as a server runtime environment in Eclipse and can now be used to deploy and run Java web modules containing Servlets, JSP files, web services and so on. Click on OK to close the Preferences dialog.

Eclipse IDE for Java EE Developers - Preferences > Server Runtime Environments > Apache Tomcat v9.0

A Dynamic Web Project in Eclipse is a project facet for developing Java web applications as defined in the Servlet Specification. It generates a web application deployment descriptor (web.xml) and allows to export the project to a web archive (WAR) file for deployment to a Servlet container such as Tomcat.

  • On the Eclipse Welcome page, select Create a new Java EE Web Project or use the Eclipse main menu and select File > New> Dynamic Web Project. Both links will show the same dialog for configuring a new dynamic web project.

Eclipse IDE for Java EE Developers > Create a new Java EE Web Project

  • In the Dynamic Web Project dialog, enter the project’s name and select the target runtime, in this case Apache Tomcat v9.0.
  • Select the Dynamic web module version, in this case it is 3.1, indicating Servlet Specification 3.1, then click on the Finish button.

Eclipse IDE for Java EE Developers > Create a Dynamic Web Project

  • The new dynamic web project will now show up in the Project Explorer of Eclipse. To open the Project Explorer, navigate to Window> Show View > Project Explorer in the Eclipse main menu.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project

  • It may be necessary to configure the project’s build path so that the Tomcat 9 JAR files are added as a dependent library to the project. These JAR file include the Servlet API, Annotations API and others.
  • Create a new user library by navigating to Window > Preferences in the Eclipse main menu.
  • In the tree menu of the Preferences dialog, navigate to Java> Build Path> User Libraries.
  • Click on the New button to add a new user library.

Eclipse IDE for Java EE Developers > Preferences > Java > Build Path > User Libraries

  • In the New User Library dialog, enter a library name, here it is Tomcat9Library

Eclipse IDE for Java EE Developers > Preferences > Java > Build Path > User Libraries > New User Library

  • The new library now shows up in the User Library list. Click on Add External JARs to add the Tomcat JAR files to it.

Eclipse IDE for Java EE Developers > Preferences > Java > Build Path > User Libraries > Add External JARs

  • In the JAR Selection dialog, navigate to the Tomcat 9 “lib” folder. In this example, the complete folder path is c:\tomcat9\lib.
  • Select all of the JAR files in that folder and click on “Open“.

Apache Tomcat 9 lib folder JAR files

  • The JAR files are now listed under the newly created library.
  • Click on OK to close the Preferences window.

Eclipse IDE for Java EE Developers > Preferences > Java > Build Path > User Libraries > Tomcat 9 JAR files

  • Adding the library to the web project: In the Eclipse Project Explorer, right click on the project name and select Properties from the context menu.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Properties

  • In the tree menu, select Java Build Path and open the Libraries tab in the main area.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Properties > Java Build Path > Libraries

  • Click on the button Add Library and select User Library in the Add Library dialog.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Properties > Java Build Path > Libraries > Add Library > User Library

  • Select the newly created user library, in this case, Tomcat9Runtime and click on Finish.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Properties > Java Build Path > Libraries > Add Library > Select User Library to add to the classpath

  • The library is now added to the web project’s list of dependent libraries.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Properties > Java Build Path > User Library

  • When expanding the Java Resources > Libraries node in the Project Explorer tree menu, the JAR files from that library are now listed.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Java Resources > Libraries > User Library

  •  In the Project Explorer, right click on the Servlets node and use New> Servlet in the context menu.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > New Servlet

  • Alternatively, you can use the Eclipse main menu and navigate to File > New > Servlet.
  • In the Create Servlet dialog, enter the Java package and class name of the Servlet.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Create Servlet

  • Click on Next to continue. The additional dialog shows the URL mapping for the new Servlet.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Create Servlet > URL Mappings

  • Click on Finish to complete the process. Eclipse will generate the Servlet and show the generated Java code in the Java editor. By default, the HTTP request handlers doGet and doPost will be generated. In the Model-View-Controller design pattern, this generated Servlet implements the Controller, i.e. it should be used to perform business logic, access data, the Model, and then return a View. In Java web applications, views are implemented using Java Server Pages (JSP) files.
  • In this example, the doGet method of the Servlet has been changed to include one line of code that forwards the request and response objects to a JSP view file called HelloWorldView.jsp.
  • This is accomplished by using the HTTPServletRequest.getRequestDispatcher method.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Java Editor - HelloWorldServlet code

request.getRequestDispatcher("/HelloWorldView.jsp").forward(request, response);
  • To create the HelloWorldView.jsp file, right click on the project name in the Project Explorer and select New > JSP File.
  • In the New JSP File dialog, keep the WebContent as the destination folder and enter the JSP file name, then click on “Next” to continue.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > New JSP File

  • In the Select JSP Template dialog, a developer can select from a default list of templates or select a custom JSP template. Here, the default template for a JSP file with HTML markup is selected.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > New JSP File > Select JSP Template

  • Click on Finish to complete the process. Eclipse will show the new JSP file in the HTML editor.
  • In this example, the JSP was modified to output a message saying Hello World! – Welcome ${param[“name”]}, where the JSP Expression Language is used to access a HTTP GET request parameter called name and prints its value.

Eclipse IDE for Java EE Developers > Project Explorer > Dynamic Web Project > Java Editor > HelloWorldView.jsp code

  • The Dynamic Web Project can be executed and debugged within Eclipse. For that, a server needs to be added to the project.
  • In the bottom area of the Eclipse IDE, switch to the Servers tab and right click to open a context menu. Then select New > Server

Eclipse IDE for Java EE Developers > Servers > New Server

  • In the Define a New Server dialog, select the previously configured Apache Tomcat v9.0 runtime environment from the dropdown control and click on the Next button.

Eclipse IDE for Java EE Developers > Servers > Define a New Server > Apache Tomcat v9.0

  • Use the Add > button to move the dynamic web project to the Configured list and then click on Finish to complete adding the Tomcat 9 server to the project.

Eclipse IDE for Java EE Developers > Servers > New Server > Add and Remove Projects

  • The Tomcat v9.0 server is now listed on the Servers tab and shows the web project that has been added to it. The server can be started by right clicking on the server name and selecting Start from the context menu.

Eclipse IDE for Java EE Developers > Servers > Start Server

  • The Tomcat 9 server will start and the dynamic web project will be automatically deployed and started as well. The Console tab in Eclipse will show the server status and any errors that occur when running the web project.

Eclipse IDE for Java EE Developers > Servers > Standard Output Console

  • Eclipse provides a built-in web browser that can be used to access the JSP file. Switch to the Internal Web Browser tab or use Window > Show View > Other > Internal Web Browser and enter the URL:
http://localhost:8080/SampleWebProject/HelloWorldServlet?name=John Smith
  • Any other external web browser can be used to access the running web project as well.

Eclipse IDE for Java EE Developers > Internal Web Browser

In order to deploy a dynamic web project on a Java EE compliant application server (such as JBoss or IBM Websphere) or on a Servlet container (such as Tomcat), the project must be packaged. This is achieved by creating a web archive (WAR) file. The WAR file contains all of the project’s runtime files and dependent JAR files, if any. In Eclipse, a WAR file can be generated by exporting a dynamic web project.

  • Right click on the project name in the Eclipse Project Explorer and select Export > WAR file.

Eclipse IDE for Java EE Developers > Dynamic Web Project > Export > WAR file

  • In the WAR Export dialog window, enter the destination folder for the WAR file and click on the Finish button.

Eclipse IDE for Java EE Developers > Dynamic Web Project > Export > WAR Export

  • The WAR file is essentially a ZIP file that contains all of the project’s file that are needed for running it. The source files are not included by default. The file can be unzipped (use 7-ZIP for example) to examine its contents.

Eclipse IDE for Java EE Developers > Dynamic Web Project > Export > WAR Export > View Contents of Generated WAR File with 7-ZIP

  • In Tomcat, the WAR file can be deployed by using the Manager Application that comes with Tomcat. JBoss and IBM Websphere offer similar administrative web applications.
  • By default, the manager application is disabled for security reasons. To enable it, edit $CATALINA_BASE\conf\tomcat-users.xml to add a user with the manager-gui role as shown below.

Apache Tomcat 9 > tomcat-users.xml > Add Manager Application User with role manager-gui

  • Refer to the official Tomcat 9 documentation on how to use the Manager Application.
  • Make sure to stop the Tomcat server in Eclipse and to start Tomcat as stand-alone as shown in section 2 of this post using  $CATALINA_BASE\bin\startup.bat
  • Access the Manager Application using a web browser and the default URL:
http://localhost:8080/manager
  • When promped enter the user name and password as set in the tomcat-users.xml file.
  • Scroll down to the WAR file to deploy section and use the Choose File button to select a WAR file from the local disk, then click on the Deploy button.

Apache Tomcat 9 > Manager Application > WAR file to deploy

  • The deployed web application will be started automatically and is then listed in the Applications section of the Manager Application.

Apache Tomcat 9 > Manager Application > Running Applications

  • Finally, the deployed web application can be accessed with a web browser by using the application’s context path and the Servlet URL.

Accessing HelloWorld Sample Web Application Deployed on Tomcat 9 from Chrome

Creating a REST Web Service in Java with Eclipse Neon, Tomcat 9, JAX-RS Jersey 2.24 and Jackson

In this example, the Eclipse Neon Java EE IDE and the Apache Tomcat 9 web server are used to create, deploy and test a REST web service using the Jersey JAX-RS API and Jackson Parser API.

Related Posts

Summary

  1. Setup of Jersey JAX-RS API User Library in Eclipse
  2. Configuration of Dynamic Web Project for REST Web Services Development
  3. Creating a REST Web Service in Eclipse with JAX-RS Annotations
  4. Deploying and Running the REST Web Service on Tomcat 9
  5. Testing the REST Web Service with Postman

Software Downloads

  • The open-source software used in this example can be downloaded from these sources:
Java JDK, Java IDE and Servlet Container
Eclipse Neon Java EE IDE from from the Eclipse Download Page
Java JDK version 1.8.0_111 from Oracle
Jersey JAX-RS API
Jersey JAX-RS reference implementation jaxrs-ri-2.24.zip from the Jersey homepage
Jersey Media JSON Jackson jersey-media-json-jackson-2.24.jar from the Maven Repository
Jackson JAX-RS Base 2.8.4: jackson-jaxrs-base-2.8.4.jar
Jackson JAX-RS JSON Provider 2.8.4: jackson-jaxrs-json-provider-2.8.4.jar
Jackson Annotations 2.8.4: jackson-annotations-2.8.4.jar
Jackson Module: JAX-B Annotations 2.8.4: jackson-module-jaxb-annotations-2.8.4.jar
Jackson Core 2.8.4: jackson-core-2.8.4.jar
Jackson Databind 2.8.4: jackson-databind-2.8.4.jar
REST Service Testing
Postman Google Chrome App from the Chrome store

A Dynamic Web Project in Eclipse is a project facet for developing Java web applications as defined in the Servlet Specification. It provides means to export the project to a web archive (WAR) file for deployment to a Servlet container such as Tomcat.

Jersey RESTful Web Services in Java - Download

  • Save the ZIP file and unzip it to some folder on the hard disk. Going forward, this folder is called Jersey API root. It contains the files shown below:

Jersey RESTful Web Services in Java - Installation folder

  • In Eclipse, navigate to Window > Preferences in the main menu and open Java > Build Path > User Libraries in the Preferences tree menu as shown below.
  • Click on the New button to setup a new user library for the Jersey REST API.

Eclipse - Java Build Path - Preferences - User Libraries

  • Enter a descriptive name for the user library and click on OK.

Eclipse - New User Library - Enter library name

  • The Jersey REST API is now listed under User Libraries. Highlight the library and click on Add External JARs.

Eclipse - Java Build Path - User Library JAX-RS-Jersey-API

  • Navigate to the Jersey API root folder and add the JAR file from the api folder.

Jersey RESTful Web Services in Java - javax.ws.rs-api-2.0.1.jar API file

  • Repeat the step and add all JAR files from the lib folder.

Jersey RESTful Web Services in Java - lib JAR files

  • Repeat the step again and add all JAR files from the ext folder.

Jersey RESTful Web Services in Java - ext JAR files

  • The imported JAR files will now be listed underneath the JAX-RS-Jersey-API library.

Jersey RESTful Web Services in Java - Eclipse user library

  • Click on OK to complete the new user library setup for Jersey JAX-RS development.

  • An existing dynamic web project in Eclipse needs to be configured properly in order to add support for the development of REST web services.
  • If you don’t have a dynamic web project setup, please refer to the below post for step-by-step instructions:
  • Open the project in the Eclipse Project Explorer and right click on its name and select Properties.
  • In the Project Properties dialog, navigate to Project Facets in the tree menu and make sure that the Dynamic Web Module version is set to 3.0 or higher.
  • Check the JAX-RS (REST Web Services) project facet checkbox and set the version to 2.0.

Eclipse - Project Facets - JAX-RS (REST Web Services)

  • Click on the link Further configuration available…
  • In the JAX-RS Capabilities dialog, select User Library from the JAX-RS Implementation Library dropdown and check the checkbox of the user library that contains the Jersey JAR files.
  • Check the checkbox for Include this library with this application.
  • Do not check the checkbox for Update Deployment Descriptor. This would cause Eclipse to generate a default web.xml file. In this example, only annotations are used.
  • Click on OK to close the dialog and then click OK again to close the project properties dialog.

Eclipse - Project Facets - JAX-RS Capabilities - Select JAX-RS Implementation Library

  • The JAX-RS-Jersey-API library will now be listed under the Libraries node in the Project Explorer.

Eclipse - Project Explorer - JAX-RS User Library in Java Resources

  • When expanding the JAX-RS-Jersey-API node, all JAR files in the library can be viewed.

Any new or existing plain old Java object (POJO) can be converted into a REST resource by using annotations form the Jersey JAX-RS API. By default, Jersey does not include a JSON parser and support for JSON marshaling/unmarshaling annotations (…conversion between Java beans and JSON and vice versa). A JSON parser API needs to be added as another user library to the dynamic web project.

  • Create another user library (e.g.: Jackson-Parser-API) as shown in section 2 and add the 7 JAR files.
  • Add the Jackson-Parser-API user library to the Java Build Path of the project as shown below.

Eclipse - Java Build Path - Jackson Parser API user library

For initializing Jersey and for providing package names that contain REST resources, a separate Java class needs to be created.

  • This class is annotated with the @ApplicationPath annotation which specifies the base URI (uniform resource identifier) for REST resources within a web application.
  • In this example, the base URI for REST resources within the SampleWebProject is:

https://localhost:8080/SampleWebProject/restservices/

The below Java code of the class MyRESTServices shows an example where the Jersey ResourceConfig class is used to create a new REST web service application as described in the Jersey user guide.

  • Jersey will use the JSON parser in com.fasterxml.jackson.jaxrs.json (Jackson-Parser-API library)
  • Jersey will look for JAX-RS annotated Java classes in the package com.pegaxchange.java.web.rest.
  • For more information on the annotations etc., please refer to the Jersey documentation.
package com.pegaxchange.java.web.rest;

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("restservices")
public class MyRESTServices extends ResourceConfig {

    public MyRESTServices() {
        packages("com.fasterxml.jackson.jaxrs.json");
        packages("com.pegaxchange.java.web.rest");
    }
}
  • A Java class can be annotated with the @Path annotation to expose it as a REST resource.
  • Public methods can be annotated with @GET and @POST to handle HTTP GET and POST requests.
  • The @Consumes and @Produces annotations can be used to specify request and response formats such as XML and JSON.

The below ProductCatalogResource Java class represents a product catalog that can be accessed through a REST interface. It exposes 3 methods:

  • The method searchByCategory handles HTTP GET calls to search the catalog by product category.
  • The category name is passed as a URI path parameter using the annotations:

@Path(search/category/{category}) and @PathParam("category")

  • The method searchByName searches the catalog by product name, which is passed as a query parameter using the  @QueryParam("name") annotation.
  • The method insert adds a product to the catalog. It receives a JSON encoded product from the HTTP POST request, inserts the product and returns a JSON string with a status message.
package com.pegaxchange.java.web.rest;

import java.util.*;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import com.pegaxchange.java.bean.Product;
import com.pegaxchange.java.bean.Status;

@Path("productcatalog")
public class ProductCatalogResource {

    private static List productCatalog;

    public ProductCatalogResource() {
        initializeProductCatalog();
    }

    @GET
    @Path("search/category/{category}")
    @Produces(MediaType.APPLICATION_JSON)
    public Product[] searchByCategory(@PathParam("category") String category) {

        List products = new ArrayList();

        for (Product p : productCatalog) {
            if (category != null && category.equalsIgnoreCase(p.getCategory())) {
                products.add(p);
            }
        }

        return products.toArray(new Product[products.size()]);
    }
    
    @GET
    @Path("search")
    @Produces(MediaType.APPLICATION_JSON)
    public Product[] searchByName(@QueryParam("name") String name) {

        List products = new ArrayList();

        for (Product p : productCatalog) {
            if (name != null && name.toLowerCase().startsWith(p.getName().toLowerCase())) {
                products.add(p);
            }
        }

        return products.toArray(new Product[products.size()]);
    }
    
    @POST
    @Path("insert")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Status insert(Product product) {
        productCatalog.add(product);
        return new Status("SUCCESS", "Inserted " + product.getName());
    }

    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, "Screwdriver", "Hardware", 7.95D));
            productCatalog.add(new Product(6, "English Dictionary", "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));
            productCatalog.add(new Product(10, "Smart Thermostat", "Electronics", 1199.19D));
        }
    }
}
  • The Product Java bean class shown below is annotated with @XmlRootElement to support XML binding and to allow Jackson to generate JSON and XML representations of Java objects.
package com.pegaxchange.java.bean;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Product implements Serializable {

    private static final long serialVersionUID = 6826191735682596960L;

    private int id;
    private String name;
    private String category;
    private double unitPrice;
    
    public Product() {} // needed for JAXB

    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;
    }
}
  • The Status Java bean class is used for returning a message when a new product was inserted using the insert method.
package com.pegaxchange.java.bean;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Status implements Serializable {

    private static final long serialVersionUID = -9130603850117689481L;

    private String status;
    private String message;
    
    public Status() {} // needed for JAXB
    
    public Status(String status, String message) {
        this.status = status;
        this.message = message;
    }
    
    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
    
    public String getMessage() {
        return message;
    }
    
    public void setMessage(String message) {
        this.message = message;
    }
}

  • Before deploying the project as a WAR file to an external Tomcat 9 server from within Eclipse, it is necessary to configure the project’s Deployment Assembly.
  • The JAX-RS-Jersey-API user library should already be listed due to the earlier JAX-RS facet setup.
  • The Jackson-Parser-API user library needs to be added manually. Click on the Add… button.

Eclipse - Web Deployment Assembly

  • Select Java Build Path Entries as the directive type and click on Next > to continue.

Eclipse - Web Deployment Assembly - Add new assembly directive from Java build path entries

  • Select the Jackson-Parser-API user library that was configured earlier and click on Finish.

Eclipse - Web Deployment Assembly - Add new assembly directive from user library

  • The Jackson-Parser-API will now be listed as a source for deployment assembly and its JAR files will be added to the web application’s WAR file in the WEB-INF/lib folder.
  • Click on OK to complete the deployment assembly setup.

Eclipse - Web Deployment Assembly - Define packaging structure for this Java EE Web Application project

  • To deploy the project, right click on the project name in the Eclipse Project Explorer and select Export > WAR file from the context menu.

Eclipse - Project Explorer - Export dynamic web project as WAR file

  • In the below example, the WAR file is directly saved into the Tomcat server’s webapps folder. Tomcat will automatically deploy the web application and start it.

Eclipse - WAR Export - Tomcat webapps destination folder

  • Alternatively, the Tomcat manager app can be used to deploy the WAR file and to stop and restart the REST service application.

Apache Tomcat 9 - Manager application

  • A browser can be used to test the exposed methods that use HTTP GET and a REST service testing tool such as Postman can be used to test the methods that require HTTP POST requests.

Postman is a free Google Chrome based application for testing REST web services and APIs. It can be downloaded from here.

  • Open Postman and enter the URL for the REST service, in this case, the URL for searching the product catalog based on a URI path parameter for the category name is:

https://localhost:8080/SampleWebProject/restservices/productcatalog/search/category/electronics

  • The REST web service returns a JSON array of products in the given category as shown in the below screen shot where the category name is electronics.

Postman - HTTP GET request for searching product catalog by category

  • The search method allows to search for a product by name. In this case, the name is included in the URL as a query string parameter:

https://localhost:8080/SampleWebProject/restservices/productcatalog/search?name=Hammer

  • And the service returns a JSON array of products where the name is hammer.

Postman - HTTP GET request for searching product catalog by name

  • The insert method of the REST service allows to add a product to the catalog. This method is invoked via HTTP POST and the product to be added is passed as a JSON encoded string in the request body. The URL in this case is:

https://localhost:8080/SampleWebProject/restservices/productcatalog/insert

Postman - HTTP POST request for inserting a new product into the catalog

  • This method returns a JSON encoded status message -using the @Produces annotation and the Status Java bean as the return type- indicating that the insert was successful and reflecting the name of the inserted product.

Links to Relevant Documentations

  1. Jersey 2.24 User Guide
  2. Java API For JSON Processing
  3. Java Doc of JAX-RS 2.0 API Specification
  4. Oracle Example on Building RESTful Web Services with JAX-RS

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