Example 41.2. Method for Getting the Message Payload in a Logical Handler

LogicalMessage getMessage();

Once you have the LogicalMessage object, you can use it to manipulate the message body. The LogicalMessage interface, shown in Example 41.3, “Logical Message Holder”, has getters and setters for working with the actual message body.

The contents of the message payload are determined by the type of binding in use. The SOAP binding only allows access to the SOAP body of the message. The XML binding allows access to the entire message body.

Working with the message body as an XML object

One pair of getters and setters of the logical message work with the message payload as a javax.xml.transform.dom.DOMSource object.

The getPayload() method that has no parameters returns the message payload as a DOMSource object. The returned object is the actual message payload. Any changes made to the returned object change the message body immediately.

You can replace the body of the message with a DOMSource object using the setPayload() method that takes the single Source object.

Working with the message body as a JAXB object

The other pair of getters and setters allow you to work with the message payload as a JAXB object. They use a JAXBContext object to transform the message payload into JAXB objects.

To use the JAXB objects you do the following:

Get a JAXBContext object that can manage the data types in the message body.

Put the updated message body back into the context as shown in Example 41.5.

Example 41.5. Updating the Message Body Using a JAXB Object

message.setPayload(body, jaxbc);

Working with context properties

The logical message context passed into a logical handler is an instance of the application's message context and can access all of the properties stored in it. Handlers have access to properties at both the APPLICATION scope and the HANDLER scope.

Like the application's message context, the logical message context is a subclass of Java Map. To access the properties stored in the context, you use the get() method and put() method inherited from the Map interface.

By default, any properties you set in the message context from inside a logical handler are assigned a scope of HANDLER. If you want the application code to be able to access the property you need to use the context's setScope() method to explicitly set the property's scope to APPLICATION.

Determining the direction of the message

It is often important to know the direction a message is passing through the handler chain. For example, you would want to retrieve a security token from incoming requests and attach a security token to an outgoing response.

The property is stored as a Boolean object. You can use the object's booleanValue() method to determine the property's value. If the property is set to true, the message is outbound. If the property is set to false the message is inbound.

Determining the return value

How the handleMessage() method completes its message processing has a direct impact on how message processing proceeds. It can complete by doing one of the following actions:

Return true—Returning true signals to the Apache CXF runtime that message processing should continue normally. The next handler, if any, has its handleMessage() invoked.

Return false—Returning false signals to the Apache CXF runtime that normal message processing must stop. How the runtime proceeds depends on the message exchange pattern in use for the current message.

For request-response message exchanges the following happens:

The direction of message processing is reversed.

For example, if a request is being processed by a service provider, the message stops progressing toward the service's implementation object. Instead, it is sent back towards the binding for return to the consumer that originated the request.

Any message handlers that reside along the handler chain in the new processing direction have their handleMessage() method invoked in the order in which they reside in the chain.

When the message reaches the end of the handler chain it is dispatched.

For one-way message exchanges the following happens:

Message processing stops.

All previously invoked message handlers have their close() method invoked.

The message is dispatched.

Throw a ProtocolException exception—Throwing a ProtocolException exception, or a subclass of this exception, signals the Apache CXF runtime that fault message processing is beginning. How the runtime proceeds depends on the message exchange pattern in use for the current message.

For request-response message exchanges the following happens:

If the handler has not already created a fault message, the runtime wraps the message in a fault message.

The direction of message processing is reversed.

For example, if a request is being processed by a service provider, the message stops progressing toward the service's implementation object. Instead, it is sent back towards the binding for return to the consumer that originated the request.

Any message handlers that reside along the handler chain in the new processing direction have their handleFault() method invoked in the order in which they reside in the chain.

When the fault message reaches the end of the handler chain it is dispatched.

For one-way message exchanges the following happens:

If the handler has not already created a fault message, the runtime wraps the message in a fault message.

Message processing stops.

All previously invoked message handlers have their close() method invoked.

The fault message is dispatched.

Throw any other runtime exception—Throwing a runtime exception other than a ProtocolException exception signals the Apache CXF runtime that message processing is to stop. All previously invoked message handlers have the close() method invoked and the exception is dispatched. If the message is part of a request-response message exchange, the exception is dispatched so that it is returned to the consumer that originated the request.