Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
HydraExpress Web Service Development Guide
Rogue Wave web site:  Home Page  |  Main Documentation Page

14.4 Creating Your Own Handlers

This section includes a simple example for creating your own handlers. It uses an example in the <installdir>\examples\webservices\Handlers directory. This directory contains provided client and server implementations, two handler classes, and configuration files required to configure the handlers.

On the client, we will add two handlers to the proxy: a request handler and a transport handler.

On the server, the same handler will take the SOAP header and perform special processing before adding a response header back in for the response message.

Creating a customized handler is a simple task, requiring the following basic steps:

14.4.1 Generate Code

Before we create a custom handler, we'll generate code from the supplied handlers.wsdl. Open a command prompt and change to the directory <installdir>\examples\webservices\Handlers. Then generate code as following:


The HydraExpress project file example-project.xml includes all options and files to be used as an argument to the code generator, so using this file results in exactly the same generated code as providing the options and files directly. For more information on the use of HydraExpress project files in the shipped examples, see Section 1.5.1, "The Use of the HydraExpress Project File in Shipped Examples," in the HydraExpress User Guide.

HydraExpress will generate code based on handlers.wsdl into a directory, HandlersExample. For basic information on how to generate code, see Chapter 3, "Creating a Web Service."

Now we're ready to create a handler.

14.4.2 Write the Handler Implementation

The two handlers included in this example are SoapSecurityHandler, a request handler, and StringReverseHandler, a transport handler. Both derive from base class rwsf::MessageHandlerImp.

rwsf::MessageHandlerImp is the body class of a handle/body pair. You derive from this class and implement the method invoke(). This method takes an rwsf::CallInfo object containing any data or information to be included with the message.

14.4.2.1 Creating a Request Handler

First, we'll create a request handler to handle requests for both the client and the server. A request handler processes the message body itself.

This example uses rwsf::CallInfo's isClient() method (Section 14.2.3) to determine whether the request is client or server-based, and then either adds the SOAP header, or gets its value. Here is the included class SoapSecurityHandler.

//1

Derives from rwsf::MessageHandlerImp.

//2

If isClient is true, this is the client and not the server. If it's the client, let's add a request SOAP header containing security data.

//3

Or, if this is the server, get the client's SOAP header and add it to the response header.

14.4.2.2 Creating a Transport Handler

A transport handler processes the message after it is created and before it is transported. Our transport handler will process both the request and the response. Let's look at the transport handler class, StringReverseHandler.

//1

Derives from rwsf::MessageHandlerImp.

//2

If isRequest is true, this is a request from a client, so get it. Otherwise, this is a response from the server, so get that.

//3

Reverse the bytes in the message. This just demonstrates how to change the message before it is sent over the transport.

//4

If this is a request, add the changed message to the request; otherwise, add it to the response.

Now that you've created your handlers, they are ready to add to the client proxy.

14.4.2.3 Aborting Handler Processing

If you wish to stop the further processing of a message by the message processing layer (for instance, based on a SOAP header it contains) you may do so.

From your handler implementation, simply invoke

This method aborts the further processing of a message.

14.4.3 Add the Handlers to the Proxy

The client proxy is itself a handler, and also supports chaining handlers. For general information on how to use the client proxy, see Chapter 7, "Developing Clients."

To add new handlers to the proxy, just invoke the appropriate "add handler" methods on the proxy after you call the make() method. Following is an excerpt from the supplied implementation of the proxy, HandlersClient.cpp.

The order in which handlers are processed on the client affects which type of handlers you choose to add:

This is illustrated in Figure 8.

14.4.4 Register the Handlers

There are two ways to register your new handlers. The easiest way is to define them in the server implementation, using the macro RWSF_DEFINE_MESSAGE_HANDLER. This method is the easiest because it requires no other changes. Following is an excerpt from the supplied server implementation, HandlersImp.cpp.

//1

Include the handler header files.

//2

Use the RWSF_DEFINE_MESSAGE_HANDLER macro to register your handlers.

The disadvantage of the above method is that it ties the handlers to the service implementation when really they should be independent of it. One way to achieve a decoupling of the handlers from the service implementation is by declaring the RWSF_DEFINE_MESSAGE_HANDLER macros in the implementation files for the handlers themselves and compiling the handlers into a separate library.

To complete the registration of your handlers, simply add them to the handlers_objects.xml file. This file is loaded by the Agent at startup, making all objects in it available to any running service. Let's take a look at the relevant lines in the supplied handlers_objects.xml:

//1

Add a naming-obj element for each handler. The element must include a naming-name and a naming-class attribute.

//2

The naming-class attribute is made up of library.createClass where "library" is the name of the service and the shared library (or dll on Windows), and "Class" is the name of the class to instantiate.

14.4.5 Configure the Handlers

To configure and chain your handlers, add them to handlers_handlers.xml in the appropriate chain.

The order in which handlers are applied is based on their order in the configuration file. Transport handlers are applied symmetrically at input and output, with the first configured handler being closest to the transport, the second configured handler being second from the transport, and so on. Request and response handlers are applied in configured order in both directions.

For more information on handler processing order, see Section 14.2.

//1

Add the request handler by its name attribute and the name of its skeleton.

//2

Add the transport handler.

14.4.6 Compile and Deploy the Service

Before building this example, copy all provided sample files from <installdir>\examples\webservices\Handlers to the new HandlersExample directory, allowing the provided files to overwrite the generated files, as follows:

HandlersClient.cpp Copy to HandlersExample\app\client
HandlersImp.cpp Copy to HandlersExample\app\server
SoapSecurityHandler.h
StringReverseHandler.h
Copy to HandlersExample\app\client
handlers_handlers.xml
handlers_objects.xml
Copy to HandlersExample\conf

To compile the client and server, change to the directory HandlersExample, and run nmake (Windows) or make (Linux or UNIX).

To deploy the Agent, run nmake (Windows) or make (Linux or UNIX) for the deploy target, and then start the server.


If the Agent is already running, you must first stop it before you deploy your service, using the rwsfserver stop command.

Windows rwsfserver stop
nmake deploy
rwsfserver start
Unix/Linux rwsfserver stop
make deploy
rwsfserver start

For more information on compiling and deploying, see Chapter 22.

Change directories to HandlersExample\bin, and run the client by entering:

Windows prompt>HandlersClient.exe
Unix/Linux prompt>HandlersClient

The server should return:



Previous fileTop of DocumentContentsIndex pageNext file

Copyright © Rogue Wave Software, Inc. All Rights Reserved.

The Rogue Wave name and logo are registered trademarks of Rogue Wave Software, and HydraExpress is a trademark of Rogue Wave Software. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.