devxlogo

Build a SOAP-based Chat Application with Java Web Services

Build a SOAP-based Chat Application with Java Web Services

here are many definitions of what Web services are or should be, each more or less understandable. It’s interesting how sometimes the simplest things are the hardest to describe. With that in mind, here’s yet another take: a Web service is an entity that can exchange documents with the outer world. This entity is self descriptive and possesses a unique identity.

The document content is XML; strictly speaking SOAP. SOAP (Simple Object Access Protocol) defines the internal structure of the XML documents that Web services consume and produce. Web services speak SOAP. SOAP is recognized as an industry standard and is widely adopted across many boundaries?across software vendors, hardware platforms, operating systems or programming languages.

Every Web service has a home. This is its identity. The address is defined by a URI (also known as a URL). A Web service lives at and is identified by its URI. This address is often called an endpoint. The identity has nothing to do with security in this context. The service used in this tutorial lives at http://localhost:6060/ChatService/.

A Web service carries its own description. This tells you what kinds of documents it exchanges (the interface definition). It says where the service lives (the URI address). And it also says which transport protocols it can use for the exchange of the documents (the binding). The language used for the Web services description is WSDL (Web services Definition Language). A Web service is completely described by its WSDL document. You only need the WSDL document in order to communicate with a standalone Web service. Though WSDL describes the Web service in its own context, it says nothing about orchestration of multiple Web services.

A Web service has a home, but you need to find where it lives in order to visit it. In other words, you need a telephone book listing Web services. UDDI (Universal Description, Discovery and Integration) is the industry standard telephone book. UDDI deals with registering and discovering Web services.

Putting it all together, a Web service is an entity that exchanges SOAP documents with the world, is located at some URI, is described with a WSDL document, and can be listed and discovered in the UDDI registry.

A Dose of Reality
Countless types of documents can be sent to and received from Web services. It can be a periodic temperature report in a steel mill, it can be a tax refund request defined by the local government, or it can be a document style representation of an RPC call from one software component to another one. The same applies to the exchange scenarios. You can imagine one-way messages, or request-response messaging where a request document must be followed with the response document, or even completely asynchronous messaging where a single subscription to a service results in the periodic delivery of information. Most of the current usage of Web services follow the RPC over XML pattern. The reason for this is obvious?developers can “turn-into-Web-services” existing applications without significant code modifications, or create clients for Web services with minimal effort. Web services frameworks often hide the complexity of the underlying infrastructure. They usually provide tools for language-to-WSDL and WSDL-to-language generation. Exposing language constructs as Web services is much faster and simpler than manually dealing with XML documents. Today, Web services are frequently used as an integration tool that lets developers and system architects interconnect heterogeneous applications.

Though the Web service and its clients in this article follow the RPC over XML pattern, the application field of Web services is much broader. In the near future, there will most likey be more and more implementations based on pure document exchange patterns that are more loosely coupled.

A Simple Chat Server
In this article, I’ve attempted to create an application that is more challenging than the famous stock quote service, but is still easy to read and understand. It is a chat server application. The functionality of the chat server is very simple?clients either post new messages and/or read them.

This chat server implementation is completely orthogonal to WASP and Web services. It can be successfully compiled and used in any other Java environment. This chat server also represents pre-existing business logic. Feel free to examine the code to understand. You can download the source code for the chat implementation (but not the Web service, which isn’t written yet) here.

Design of the Chat Server
The complete implementation of the chat server is decoupled into several classes. The interface is defined in the package com.systinet.simplechat.server.iface. It consists of three classes; IChatService.java, the interface class of the chat server, and two structures that are used for the representation of chat messages and participants?ChatMessage.java and ChatPerson.java.

The implementation of the chat server is in the package com.systinet.simplechat.server.impl. It decouples the simple implementation of the interface from the backend business logic. I’ve used the Adaptor design pattern, i.e., the calls to ChatService.java are delegated to a backend processor. The business logic is pretty simple. It’s a singleton instance of the class SimpleBackendImpl.java that stores the messages in a collection.

At first glance, the adaptor/backend implementation might seem too complicated for a simple tutorial. However, even complex existing business logic can be reused to become a Web service without any need to change its code. This is a frequent real-life use case. Even if the application wasn’t designed using the Adaptor pattern originally, writing a wrapper class like ChatService can be accomplished in a matter of seconds, without the need to rewrite the original backend logic. However, the backend could have been implemented using JDBC and a relational database, or as an EJB, or even make calls to native methods of external non-Java applications. The possibilities are endless. The Adaptor pattern simply allows you to switch to new backend logic quickly.

Turning the Chat Server into a Web Service
Right now, the chat server is just a Java implementation. It is not yet SOAP aware. It’s just a working chat server for clients running in the same JVM. The next step is to make the chat server speak SOAP and create a WSDL document that describes it.

This example uses Systinet’s Web Applications and Services Platform (WASP) software to create the Web services application. WASP software is platform independent and works in almost any Java environment. This platform presents two distinct deployment scenarios: programmatic deployment and declarative deployment. In both cases what gets deployed is a plain old Java object. Programmatic deployment (also called runtime publishing) happens in an application’s runtime and enables dynamic deployment of application classes as web services. Literally, you start WASP inside your application, and register its objects with calls to the WASP API. In other words, you actually embed WASP into your application. Declarative deployment means packaging your application into a deployment package (kind of a JAR file with an included deployment descriptor) and publishing that to a running instance of WASP. For its simplicity and straightforward access, we’re using the runtime publishing method.

 
Figure 1: Import existing code.

Installing the Chat Server into Eclipse
Assuming that you have Eclipse with WASP Developer up and running, install the sample code.

  1. In Eclipse create a new project (File -> New -> Project…). Choose the Systinet Web Services/Web Service Project.
  2. In the following dialog enter the project name, ChatServiceProject and location. Finish the wizard.
  3. From the File menu, choose the Import… command, and choose the Zip file method.
  4. In the following dialog choose the zip file downloaded earlier as the source, and click on the Finish button.

Your project should now contain the two packages with the source for the Chat Service. You can verify this by examining the Package Explore view.

SOAP Enabling the Chat Server
Now you have a working implementation of a simple chat server. To make it talk SOAP, deploy it to the Web services server using the runtime publishing method.

Start the server at the specified address and register the service under a path on the server. The server address + service path make up the complete URI of the Web service.

Here’s the code of the application class that starts the SOAP server and registers the chat service as a Web service. This source file should (obviously) be saved as ChatServerApp.java.

package com.systinet.simplechat.server.impl;import org.systinet.wasp.*;import org.systinet.wasp.webservice.Registry;public class ChatServerApp {    public static void main(String[] args) throws Exception {        Wasp.startServer("http://localhost:6060");		        Registry.publish("/ChatService/", ChatService.class);		        System.out.println("The Chat server is up and running.");    }}

It’s that simple. Just two lines of code:

        Wasp.startServer("http://localhost:6060");        Registry.publish("/ChatService/", ChatService.class);

The WASP.startServer method starts the server inside a Java application. The Registry.publish method programmatically deploys the ChatService class as a Web service. The URI of this service is composed of the address of the server and of the service’s path on the server. WASP also automatically creates the WSDL document describing the service and publishes it at SERVICE_URI/wsdl.

 
Figure 2: Running the server.

Build and Run the Chat Server
The chat server is ready for running now. After the build is complete (Project -> Build Add), you can start it. First, create a Web service runner. This runner ensures that the server has all the required libraries and that it is properly configured. To create the runner, select the ChatServerApp from the com.systinet.simplechat.server.impl package and choose Run -> Run… from the IDE menu.

The dialog that opens is the manager for all runners in the project. Double click on the WASP Java Application runner template. A new runner called ChatServerApp is created. Always use this runner to run the ChatServerApp class. Press the Run button to start the chat server.

The server is up and running, ready to speak SOAP. Its location is http://localhost:6060/ChatService/. The location of the dynamically generated WSDL document is http://localhost:6060/ChatService/wsdl.

The business logic is now deployed to the server programmatically using the Runtime API.

 
Figure 3: Here’s the output of the running server.

The Client
Now, you need a client that consumes the ChatService.

Pretend that all you know about the service is the location of its WSDL description: http://localhost:6060/ChatService/wsdl. You do not have access to the original Web service’s source code. You don’t even know in what language it is implemented. You also don’t know the exact location of the ChatService, but you do know that every Web service is completely described in its WSDL document.

The server creates a proxy which hides all the SOAP and transports plumbing from developers, and lets them invoke Web services with simple method calls. In order to work, this proxy has to know the location (and therefore the content) of the Web service’s WSDL description, the URI of the Web Service, and its Java interface. You know the WSDL location of the ChatService and, as it happens, the URI of the service is contained in this WSDL. Now all you need is to get the service’s Java interface. Creating it manually means understanding the WSDL and XML Schema very well, and even then it would still be a daunting task. Fortunately, WASP Developer contains a tool that generates the Java interface of a Web service from its WSDL. This tool, called WSDL2Java, is available both as a command line utility and as an ANT task, so it is very easy to integrate with builds that use ANT.

 
Figure 4: Creating the client package.

The Client’s Code
First, create a new package for the client. From the menu, choose the File -> New -> Package. In the New Package dialog enter the package name com.systinet.simplechat.client, and press the finish button.

WASP Developer requires the WSDL file to be present in the project in order to generate the client classes. Download the Chat Service’s WSDL document into the project. Select the com.systinet.simplechat.client package, and from the menu choose File -> New -> Other…. The New dialog now opens. In the left hand bar, choose Systinet Web Services. A set of all available wizards is displayed in the right hand bar. Choose the WSDL from Internet item and proceed to the next window.

In the second window fill in the location of the WSDL file and chose Next. The ChatService’s WSDL file is located at http://localhost:6060/ChatService/wsdl.

In the last window, fill in the name of the downloaded WSDL file. Set it to ChatService and click finish.

The WSDL file is now in your project. In order to generate the client classes chose the Generate Client… item from its context menu.

When the Generate Client from WSDL wizard opens, leave all values set to their defaults and finish the wizard.

No you have created several files in two new packages; com.systinet.simplechat.client.iface and com.systinet.simplechat.client.iface.struct. The former package contains the interface definition, ChatService.java, and a support file used by the WASP framework ChatService.xmap. The latter package contains additional structures that are used in the ChatService.java interface?ChatMessage.java and ChatPerson.java. If you inspect the generated classes, they should be familiar to you. They are not exact copies of the original ChatService interface classes, but they exactly represent its API.

There’s one more class that WASP Developer has created from the WSDL file. Look at the com.systinet.simplechat.client package. There’s one new file there, ChatServiceClient.java. This is a generated skeleton of the client application. Listing 1 shows the class in it’s entirety.

First, a couple of WASP classes are imported, then you see the imports for the ChatService interface and structures that were generated from the WSDL file. The interesting part of the code is in the main() method:

        ServiceClient serviceClient = ServiceClient.create(wsdlURI, ChatService.class);        serviceClient.setServiceURL(serviceURI);        serviceClient.setWSDLServiceName(new QName("http://systinet.com/wsdl/com/systinet/simplechat/server/impl/", "ChatService"));        serviceClient.setWSDLPortName("ChatService");        service = (ChatService) Registry.lookup(serviceClient);

These lines create the proxy that the client uses for remote invocation of the Chat Service. WASP Developer generates a little more code than the simple client requires. Because WSDL files can contain information about multiple Web services, the generated code is a little bit more complicated so that it works with any WSDL file. However, the following single line of code would work the same way for our simple case:

service = (ChatService) Registry.lookup("http://localhost:6060/ChatService/wsdl/", ChatService);

The service object is now ready for calls. Every call on its methods results in remote invocation of the chat service. Finish the client with calls to the chat service. Listing 2 shows the extended, auto-generated code.

 
Figure 5: Here’s the chat client’s output.

Build and Run the Client
Now that the client is implemented you need to build and run it. To build the code, run Project -> Build All command from the menu.

To run the client, you’ll need its Web Service Runner (see above for details).

Select the ChatServiceClient class in the project and from the menu chose Run -> Run…. Double click on the WASP Java Application item. A new runner called ChatServiceClient is created and ready for use with the client. Always use this runner for running the client. Press the Run button to start the client.

The client connects to the Chat Service and calls two of its methods. The output into the console after two executions of the client should look like Figure 5.

Until Next Time
In this first tutorial, you’ve gotten an explanation of the standards that underpin Web services, and learned how to expose an existing Java application as a Web service. In the next tutorial, you’ll examine Web services security using the same application.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist