Swing and Web Services Tutorial

jet_jumbo

Swing and web services have been around for many years, however it has only been in recent times that things have gotten much easier in implementing web services and building complex Swing applications. This is mainly due to improvements in the Java language and better IDEs.

This tutorial aims to be a comprehensive guide to getting an end-to-end configuration of a Swing application communicating with a web service deployed on the server.

This tutorial also touches on Maven and the Netbeans IDE, two technologies that go hand in hand. You don’t specifically need either of these technologies to get up and running, but for the purposes of this tutorial it is highly recommended.

Part 1. Client

We are going to start off with a basic application. In our example we are going to be building an airline application that talks to a web service. Its very simple, just a table which lists all the airlines, and a button which creates a new row in the table.

Create Project

Lets create a Maven project and call it ‘client’. It is going to be our desktop client, so we want it to be packaged as a jar file.

client_server1

Write Some Swing Code

We want a simple entry point to our application, so we will add a main method to our MainFrame class which serves as the main Window for the application.

Inside out frame code you may notice an AirlinePanel class, which is basically a JPanel with a JTable and buttons. Let’s add our table inside a scrollpane, and add a button to the top. The aim of the table is to list all the airlines in the system, and the button will eventually create new rows in the table after persisting across the network.

Swing uses the MVC pattern for its complex components, so for our table object, we need to have a model object that contains the business data. Lets create AirlineTableModel, an AbstractTableModel, which acts as a model for AirlineVO objects.

So now we should have three classes :

  • MainFrame
  • AirlinePanel
  • AirlineTableModel

However AirlineVO is missing.

Create an AirlineVO class somewhere in the project. We will be deleting this local AirlineVO class a bit later, and instead we will be using the web service generated AilineVO object. But for now you can add some dummy getter and setters into the code just so that the client application code works.

Now let’s move on to the web service project.

Part 2. Webservices

Create Web Service Project

Create a web application project. In Netbeans you can do this via choosing a Web Application project.

client_server2

The Pom project you have should be named like this. We want the groupId to be the same for the client and the server. It needs to be packaged as a WAR file, and dependencies should be present which includes javaee-web-api and webservices-rt. Both these scopes should be set to PROVIDED. This basically means the web server has its own versions of these two libraries which it will use instead.

client_server3

Create the Web Service Class

Create a java class called AirlineWS. This will be our entry point for our airline application. All methods that we need will exist in this class.

On Netbeans go to New —> WebService

Annotate the class with the @WebService annotation, which tell the application server to treat the class as a web service.

Create the Value Object Class

In our client code we can see that the code uses something called an AirlineVO object. We want to define this on the server side as well. If we also have the AirlineVO defined in the web service (WSDL), then there is no need to have a separately maintained copy on the client side. The AirlineVO object can be generated via a ws-import (more on that later).

NOTE : While in this example we are using the AirlineVO object throughout the client code, this in general is bad practise. Once the VO object is received by the client, it should be converted to a client specific object: eg: Airline guiAirlineObject = new Airline(airlineVO). This reduced the dependencies on the generated code, and also allows for decorations. That is to say, it is a decorator pattern.

So we create an AirlineVO class and put it in the web server project.

Implement the WebService Methods

We can now add some business logic to the web server. Normally a web server delegates to another layer such as the EJB layer, however for demonstration purposes this web service will be our end point. In a constructor we will create some of these Value objects and put them into an array list.

We will then create a couple of methods. We need to annotate them, this way the web server know to treat them as a web service end point.

We can add a constructor which creates some dummy data. Of course we should have a proper database for our application, but for illustrative purposes this should suffice. The other two methods do a basic add, and a basic create.

Clean, Build, and Deploy

Now that we have our server code we can clean and build the project. In Netbeans there is a Clean and Build option on the context menu for the project.

client_server4

Follow this up with Run. This can also be found on the project context menu.

‘Running’ a server project in Netbeans and in most other IDEs, actually deploys the application to the server. Per default Netbeans has a Glassfish instance running on localhost, so an instance of Glassfish is booted up, if it hasn’t already been started, and the WAR file is deployed as an application.

If you visit the administration console for glassfish, you will see something like this.

client_server5

From this screen you can select ‘View Endpoint’ and view that the WSDL is there. This is what is exposed to the outside world, and is what ws-import uses to figure out what classes are needed to talk to this interface.

 

 

 

 

Part 3. Back to the Client…

Delegate

Let’s create the skeleton of a delegate class as we want to use the delegate pattern to shield the GUI code from all the backend code. Swing is also not Thread-safe so we also need to make all calls to the backend through a thread safe singleton.

WsImport

Now we need to add wsimport support. WsImport is a maven plugin that needs to be defined in the POM file, in the plugins section. The webservice endpoints that we are interested in should be defined in the <wsdlUrl> tag. In our case, it is the AirlineWS web service.

client_server6

Clean and build the client project. The wsimport plugin attaches itself to the build process, and you may notice that building has gotten a little slower. After it has finished you may now notice a folder called ‘Generated Sources (wsimport)’.

client_server7

It contains all the artefacts that the wsimport has created during the build process. We can get access to a port for a particular web service, and from that port object we can call any method we want. This is how we use the generated code to do this:

Notice how the AirlineVO class is also there. This is not the same object as exists on the server side. This object was generated based on the Web Service definition (WSDL).

Lets add two methods to the delegate object, using the generated code :

Now we can call these delegate methods from within the Swing code.

We can do two things.

  1. On the create button add an actionlistener. In a later tutorial we will add a proper dialog for creating a new airline object. For now, we just send the same data across to the server, as in this tutorial we are just interested in a proof of concept.
  2. At the end of the initComponents method we call getAll from the web service. This will getall the value object from the backend and display them in the table. We also call a getAll in the create button code, because we want to perform a refresh of the data once we have created something.

You should see something like this. The table is being filled from data supplied by the web service, and clicking on the Create button creates a new row in the table.

client_server8

 

 

(Source Code is here)

Comments are very appreciated J


Posted in Swing, Tutorial | Tagged , , , , | Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

THREE_COLUMN_PAGE