5 min read

(For more resources on Axis2, see here.)

Handler

In any messaging system, the interceptor has its factual meaning in the context of messaging, where it intercepts the flow of messaging and does whatever task it is assigned to do. In fact, an interceptor is the smallest execution unit in a messaging system, and an Axis2 handler is also an interceptor.

Handlers in Axis are stateless, that is, they do not keep their pass execution states in the memory. A handler can be considered as a logic invoker with the input for the logic evaluation taken from the MessageContext. A Handler has both read and write access permissions to MessageContext (MC) or to an incoming SOAP message.

We can consider MessageContext as a property bag that keeps incoming or outgoing messages (maybe both) and other required parameters. It may also include properties to carry the message through the execution chain. On the other hand, we can access the whole system including the system runtime, global parameters, and property service operations via the MC.

In most cases, a handler only touches the header block part of the SOAP message, which will either read a header (or headers), add a header(s), or remove a header(s). (This does not mean that the handler cannot touch the SOAP body, nor does it mean that it is not going to touch the SOAP body.) During reading, if a header is targeted to a handler and is not executing properly (the message might be faulty), then it should throw an exception, and the next driver in the chain (in Axis2, it is the Axis engine) would take the necessary action. A typical SOAP message with few headers is shown in the figure given below:

Handler and Phase in Apache Axis2

Any handler in Axis2 has the capability to pause the message execution, which means that the handler can terminate the message flow if it cannot continue. Reliable messaging (RM) is a good example or use case for that scenario, when it needs to pause the flow depending on some of the preconditions and the postconditions as well and it works on a message sequence. If a service invocation consists of more than one message, and if the second message comes before the first one, then the RM handler will stop (or rather pause) the execution of the message invocation corresponding to the second message until it gets the first one. And when it gets, the first message is invoked, and thereafter it invokes or resumes the second message.

Writing a Simple Handler

Just learning the concepts will not help us in remembering what we have discussed. For that, we need to write a handler and see how it works. Writing a handler in Axis2 is very simple. If you want to write a handler, you either have to extend the AbstractHandler class or implement the Handler interface.

A simple handler that extends the AbstractHandler class will appear as follows:

public class SimpleHandler extends AbstractHandler
{
public SimpleHandler()
{
}
public InvocationResponse invoke(MessageContext msgContext)
throws AxisFault {
//Write the processing logic here
// DO something
return InvocationResponse.CONTINUE;
}
}

Note the return value of the invoke method. We can have the following three values as the return value of the invoke method:

  • Continue: The handler thinks that the message is ready to go forward.
  • Suspend: The handler thinks that the message cannot be sent forward since some conditions are not satisfied; so the execution is suspended.
  • Abort: The handler thinks that there is something wrong with the message, and cannot therefore allow the message to go forward.

In most cases, handlers will return InvocationResponse.CONTINUE as the return value.

When a message is received by the Axis engine, it calls the invoke method of each of the handlers by passing the argument to the corresponding MessageContext. As a result of this, we can implement all the processing logic inside that method. A handler author has full access to the SOAP message, and also has the required properties to process the message via the MessageContext. In addition, if the handler is not satisfied with the invocation of some precondition, the invocation can be paused as we have discussed earlier (Suspend).

If some handler suspends the execution, then it is its responsibility to store the message context, and to forward the message when the conditions are satisfied. For example, the RM handler performs in a similar manner.

Phase

The concept of phase is introduced by Axis2, mainly to support the dynamic ordering of handlers. A phase can be defined in a number of ways:

  • It can be considered a logical collection of handlers.
  • It can be considered a specific time interval in the message execution.
  • It can be considered a bucket into which to put a handler.
  • One can consider a phase as a handler too.

A flow or an execution chain can be considered as a collection of phases. Even though it was mentioned earlier that an Axis engine calls the invoke method of a handler, that is not totally correct. In fact, what the engine really does is call the invoke method of each phase in a given flow, and then the phase will sequentially invoke all the handlers in it (refer to the following figure). As we know, we can extend AbstractHandler and create a new handler; in the same way one can extend the Phase class and then create a new phase. But remember that we need not always extend the Phase class to create a new phase. We can do it by just adding an entry into axis2.xml (All the configuration that requires starting axis2 is obtained from axis2.xml). A phase has two important methods—precondition checking and postcondition checking. Therefore, if we are writing a custom phase, we need to consider the methods that have been mentioned. However, writing a phase is not a common case; you need to know how to write a handler.

LEAVE A REPLY

Please enter your comment!
Please enter your name here