The NWS Tutorial

Implementation of Web Services



WARNING: This tutorial is being written! Do not hesitate to report any errors or suggestions.

Quick access:
   General concepts
   SOAP (Simple Object Access Protocol) and WSDL (Web Service Description Language)
   Presentation of the API JAX-WS
   Deployment of a Web service in a web application
   Calling a web service in Java
   Exchanging objects through a Web service

General concepts

A Web service is an object hosted by a HTTP server on which it is possible to invoke methods remotely. Each method call is made by carrying the value of parameters through a HTTP request (from the client post to the HTTP server) and by carrying the return value of the distant method considered through a HTTP response (from the server to the client). Another feature of the Web services is in the interoperability of the technology: whether the client code or the Web service, they can both be developed through different technologies (Java, .Net, PHP, ...).

In fact, the technology relating to the Web services is a recommendation from the W3C (World Wide Web Consortium: http://www.w3.org ). The W3C is a consortium of many companies with an interest in promoting and developing the Web technologies. The recommendation is the most successful level in the process of standardization of the W3C. the Web services represent a mature technology: as such, it is notably supported by the Java SE 6.0.

The advantage of this technology is to put the presented datas on the web available to physical persons (through the web pages) but also to some programs (through the Web services). We can therefore imagine two Web servers, for two different companies, exchanging datas through this technology with the aim of producing a single trading proposition and integrating informations from the two companies involved. In such a case the two servers exchange the information with simple calling methods (with parameters and values of return) on objects of type "web service".

The interest to host your Web services by an HTTP server lies in the fact that by default, the networks requests/responses are using the port 80. If between the client making the request and the server that provides the service, the network infrastructure used put in game firewalls or HTTP proxy, it will not create any problem because on these systems, the port 80 is normally open. You can also note that the use of the web services may allow you to build a SOA Architecture (Service Oriented Architecture).

SOAP (Simple Object Access Protocol) and WSDL (Web Service Description Language)

With the Web services, the requests and the HTTP responses will contain some structured informations through the XML syntax (it is also a recommendation of the W3C). Don't remember that XML is a meta language: it is used to produce adapted languages to your needs, but based on a syntax with tags. For more informations on XML, i refer you to our XML tutorial.

Two XML languages (also known as XML grammar) are very important for the understanding for the running of the Web services. This is SOAP (Simple Object Access Protocol) and WSDL (Web Service Description Language).

SOAP makes it possible to structure the datas that will be exchanged between the service user and the provider (the Web service). Although we can consider other alternatives to XML, that choice can easily ensure the interoperability. Indeed, it exists any XML parsers on nearly all the platforms (Solaris, Linux, ...) and for all the languages (Java, C++, PHP, ...).

The interest of WSDL is a little more subtle to discern. Let's say, for simplicity that the two teams that will develop the Web service and the consumer code of the Service, are not required to know one another. They can, moreover, be located anywhere on the earth, it will not hamper for the proper functioning of the model. However, a calling method on a distant object, in the absolute, do not want to say anything: if we go down at the machine code, we can say that a calling method can operate only within a single process (at least for the modern processors). So, the call at the client application is made between your code and the local agent of the Web service. That local agent (often called proxy - not to be confused with the HTTP proxy) allows us to "simulate" the distant call in the way that it behaves like the distant object. It provides exactly the same methods, but their implementations are responsible for producing the HTTP communication. The question is to know how we generate this local agent. This is where the WSDL is starting: this description of the accessible methods through this web service will use to a tool (wsimport avec le Java SE 6.0) to generate the proxy. Moreover, the WSDL can be retrieved through a simple HTTP request on the service. So yes, the two development teams may not know each other and not have discussed on how to use the Web service considered.

Presentation of the API JAX-WS

Historically, the first API that allowed the development of Web services with the Java language was JAX-RPC. This model was relatively heavy to implement and did not use the latest object technologies introduced in the Java SE 5.0 (i think, of course, the Java annotations). These considerations were successful in producing a second model for implementing the Web service.

It is now preferable to use the API JAX-WS (Java API for XML - Web Services), now in version 2.1. This API is mainly localized in the package javax.jws. If you care to open the Javadoc on this package, you will find that it consists of a certain number of annotations (javax.jws.WebService and particularly javax.jws.WebMethod). This is because the new API of web services implementation is very simple to use: you just have to code a traditional Java class and to join it a certain number of annotations to describe the methods which will be accessible through the outside.

For example, we will consider an application of online chat accessible through the Web. This application is divided into two separate parts: the client bracket that displays the exchanged messages and the server component acting as the chat room. This is on this last part that we will begin to focus our attention. The implementation, you will see, is relatively simple. Only one class of type web service will be sufficient to encode the server part. We call this class ChatRoomServiceImpl. Note that this class is part of the demonstration application of the NWS framework.

This class will include five methods accessible through HTTP: subscribe, unsubscribe, sendMessage, getMessages and getUsers. Here's a quick description of the responsibility of each of these methods.

Here is the complete code of the chat room class. Note the use of the JAX-WS annotations. You can also note that a static method main is associated: it helps to launch the web service in stand-alone without necessarily requiring a HTTP server. This is very convenient to test the web service.

 
01 package corelib.services.web.samples.virtualcaddy.webservices;
02
03 import java.util.ArrayList;
04 import java.util.Hashtable;
05
06 import javax.jws.WebMethod;
07 import javax.jws.WebService;
08 import javax.xml.ws.Endpoint;
09
10 @WebService(serviceName = "ChatRoomService", name = "ChatRoom")
11 public class ChatRoomServiceImpl {
12
13     private Hashtable<String, ArrayList<String>> userMessages =
14                 new Hashtable<String, ArrayList<String>>();
15
16     @WebMethod public synchronized void subscribe( String pseudo ) {
17         sendMessage( "ChatRoom", "User " + pseudo + " connected" );
18         userMessages.put( pseudo, new ArrayList() );
19     }
20
21     @WebMethod public synchronized void unsubscribe( String pseudo ) {
22         userMessages.remove( pseudo );
23         sendMessage( "ChatRoom", "User " + pseudo + " disconnected" );
24     }
25
26     @WebMethod public synchronized void sendMessage( String pseudo, String message ) {
27         String fullMessage = pseudo + " >>> " + message;
28         System.out.println( fullMessage );
29         for ( ArrayList<String> array : userMessages.values() ) {
30             array.add( fullMessage );
31         }
32     }
33
34     @WebMethod public synchronized ArrayList<String> getMessages( String pseudo ) {
35         if ( pseudo == null ) return null;
36         ArrayList<String> messages = (ArrayList) userMessages.get( pseudo );
37         if ( messages == null ) return null;
38         userMessages.put( pseudo, new ArrayList() );
39         return messages;
40     }
41
42     @WebMethod public synchronized ArrayList<String> getUsers() {
43         ArrayList<String> users = new ArrayList();
44         if ( users == null ) return null;
45         for( String user : userMessages.keySet() ) users.add( user );
46         return users;
47     }
48
49     public static void main( String[] args ) {
50         // For standalone tests
51         Endpoint.publish( "http://localhost:8080/webapp/simple", new ChatRoomServiceImpl() );
52     }
53
54 }
Class "corelib.services.web.samples.virtualcaddy.webservices.ChatRoomServiceImpl"

Warning: this code is a prototype: it could without difficulty be improved to enable it to run even deeper. For example, with this implementation, if two users are connected with exactly the same name, the things may not be fine.

Deployment of a Web service in a web application

To deploy the web service on a HTTP server (Tomcat in this case), two last stages are required. The first is to add a configuration in the file WEB-INF/web.xml. The NWS framework operates two types of web components: the web pages (with an extension .wp) and the web services (with an extension .ws). The proposed extensions are not imposed: if you want to change, you can. You could even ensure that these two types of components use the same extension. But, the proposal that is made has the advantage of reminding us immediately the file nature of which we have to do. Here is the minimum configuration for invoking a Web service (see lines 19 to 22).

 
01 <?xml version='1.0' encoding='UTF-8'?>
02 <!DOCTYPE web-app PUBLIC
03   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
04   "http://java.sun.com/dtd/web-app_2_3.dtd">
05 <web-app>
06 
07     <!-- Begin of file -->
08 
09     <servlet>
10         <servlet-name>NWS Servlet</servlet-name>
11         <servlet-class>corelib.services.web.server.ControllerServlet</servlet-class>
12     </servlet>
13 
14     <servlet-mapping>
15         <servlet-name>NWS Servlet</servlet-name>
16         <url-pattern>*.wp</url-pattern>
17     </servlet-mapping>
18 
19     <servlet-mapping>
20         <servlet-name>NWS Servlet</servlet-name>
21         <url-pattern>*.ws</url-pattern>
22     </servlet-mapping>
23 
24     <!-- End of file -->
25 
26 </web-app>
File "WEB-INF/web.xml"

The second step is to define the file of extension .ws which will serve as a point of invoking the Web service (known as "end point"). This file looks, in some ways, to a NWS Web page in the sense that it referred to the class of the web service to use. Eventually, the NWS framework is expected to add other informations in this file.

 
01 <?xml version="1.0" encoding="ISO-8859-1" ?>
02 <web:Service xmlns:web="corelib.services.web.webservices"
03           	 codeBehind="corelib.services.web.samples.virtualcaddy.webservices.ChatRoomServiceImpl" />
File "ChatRoom.ws"

You can now deploy your Web application on your HTTP server. To test that the Web service is correctly deployed, you can invoke the following url: http://localhost:8080/VirtualCaddy/ChatRoom.ws?wsdl. If everything goes well, the WSDL of your service should be returned to you.

For those who have already tested the solutions for the deployment of web services under Metro (or Glassfish), you can note this: the generations of the proxy server as well as the one of the WSDL (normally done through the tool wsgen provided by the Java SE) are completely automated here. It was at the first invocation of the Web service that the missing informations will be produced. It follows an important point: to run, NWS needs a Java SE 6.0 (not a JRE) otherwise the production tool wsgen will not be available.

Calling a web service in Java

We can now just use our web service. In the client part (Javascript) of the NWS tutorial, the Web service deployed in this document will be used through a web interface using Javascript to perform the calls on the methods carried by our web service. Nevertheless, we will only, at this time, to make some test calls in Java.

The first thing to do to code our client application is to generate the proxy client. To do so, the Java SE 6.0 brings at our disposition the tool wsimport. This tool takes in the command line parameter the web address of the WSDL of your service. The following command line should allows you to produce this proxy. Note that the files .class are directly produced (you may also ask to obtain .java: option -keep).

 
wsimport http://localhost:8080/VirtualCaddy/ChatRoom.ws?wsdl

Then you need to encode your client application. In the example below, we concentrate us on the subscribe to the chat room, to send a message, to ask all our available messages, to list the connected users and finally to unsubscribe us from this chat room (all this sequentially).

 
01 import corelib.services.web.samples.virtualcaddy.webservices.*;
02 import java.util.*;
03
04 public class Client {
05
06     public static void main( String [] args ) {
07
08         ChatRoom room = new ChatRoomService().getChatRoomPort();
09         room.subscribe( "Donald" );
10         List users = room.getUsers();
11         for( Object user : users ) System.out.println( user );
12         room.sendMessage( "Donald", "Trop fort" );
13         List messages = room.getMessages( "Donald" );
14         for( Object message : messages ) System.out.println( message );
15         room.unsubscribe( "Donald" );
16
17     }
18
19 }
Example usage of a Web service from Java

Now you can compile your client application and execute it. Normally it should be connected properly to your web service. And you should pass on the messages in the log of the HTTP server used.

Exchanging objects through a Web service

Web services can also allow you to exchange parameters (as well as a return value of method) of object type. To do this, the classes used for the exchanged data must provide a default constructor. If this is not the case, an exception will be triggered. Again, the demonstration application of the NWS framework offers you a small example of implementation: you will find here a web service that allows to retrieve an item presented in the catalog or, frankly, all the articles in this catalog. Here is the code of this web service.

 
01 package corelib.services.web.samples.virtualcaddy.webservices;
02
03 import javax.jws.WebMethod;
04 import javax.jws.WebService;
05
06 import corelib.services.web.samples.virtualcaddy.business.Article;
07 import corelib.services.web.samples.virtualcaddy.business.ArticleHome;
08
09
10 @WebService(serviceName = "CatalogBrowserService", name = "CatalogBrowser")
11 public class CatalogBrowserServiceImpl {
12
13     @WebMethod
14     public Article [] getAllArticles() {
15         return ArticleHome.findAll();
16     }
17
18     @WebMethod
19     public Article getArticle( int idArticle ) {
20         return ArticleHome.findByPrimaryKey( idArticle );
21     }
22
23 }
Class "corelib.services.web.samples.virtualcaddy.webservices.CatalogBrowserServiceImpl"

It is important to understand that the Web service could be used by another language that Java (.NET, JavaScript, ...). The terminology for the exchange of objects may be a bit exaggerated. In fact, only the data objects will be transferred between the client and the web service (and not the methods, which the code is specific to a runtime environment). The client application will therefore seek to represent the objects of the web sevices, through any similar types, but that only expose the public properties of the servers objects.


CAUTION : NWS is proposed to you in BETA version to allow evaluation of this framework. Infini Software is released from any responsibility for the use of framework NWS. In addition, Infini Software can in no way be liable for the use of information contained in these tutorials.

Dominique LIARD - © 2007 SARL Infini Software - All rights reserved
Other brands and product names in these documents are the property of their respective owners.