The SOAP-RP profile is an implementation of the SOAP WS-Routing specification (formerly known as the SOAP Routing Protocol), which can be downloaded from http://msdn.microsoft.com/ws/2001/10/Routing. Although a full discussion of the specification is outside the scope of this book, this section contains a brief overview and a description of the API that JAXM provides to allow the construction of messages that conform to the specification.
SOAP-RP defines a SOAP header and a set
of rules to be followed that enable a SOAP message to be routed from
a sender, through zero or more intermediate systems to its final
destination. The SOAP-RP header, which is called
path
, contains child elements from the set listed
in Table 4-4.
Table 4-4. SOAP-RP header elements
Element |
Description |
---|---|
Contains the URI of the ultimate destination of the message. This element is added by the sender and cannot be changed as the message passes through intermediate systems. | |
Contains a URI that identifies the sender of the message. | |
If present, this tag contains zero or more URIs that define a list of
intermediate systems that must be visited before the message is
delivered to its final recipient. All of the systems in this list
must be visited in the order in which they appear. If this is not
possible, the message is discarded and a fault is returned (see the
Each URI is enclosed in a child element called
| |
If present, this tag allows a reverse path to be created as the
message traverses the route from sender to receiver. Each
intermediate system that handles the message typically inserts its
own URI as the first child of this element, in the form of a
The final recipient of a SOAP message that contains a reverse path
usually extracts it and stores it as the The | |
Contains a URI that defines the intent of the message. Its meaning is private to the application and therefore there is no well-known set of permitted action values. This element must be set by the sender and cannot be modified by intermediate systems. | |
Contains a URI that uniquely identifies the message in which it is contained. The identifier is used to link a reply or a fault to the original message that caused it to be sent. | |
Contains the value of the | |
Used to report an error condition detected when trying to route or
handle a SOAP-RP message. The reason for a fault is described by two child elements that must
always be present. The |
The path
element and all of its child elements are
defined in the namespace associated with the URI http://schemas.xmlsoap.org/rp.
In outline, here is how the
SOAP-RP path
header
is used when routing a message:
The message originator constructs a path containing an
id
element to uniquely identify the message and anaction
element that specifies what the receiver should do with the message. It may also include ato
element, afwd
element, afrom
element, and arev
element. If it is present, theto
element indicates the URI of the intended recipient. Thefwd
element may contain an ordered set of URIs that determine the route to be taken to reach the recipient. If the header does not contain ato
element, then the last entry in thefwd
element must be the URI of the target system. Arev
element is included only if a reverse path is to be created and would normally be empty.The message originator sends the message to the first intermediary system.
The intermediate system looks for a
via
element in thefwd
element of thepath
header of the received message. If such an element exists, it must contain the intermediate system’s own URI; if it does not, a fault is generated and returned to the sender. Assuming that thevia
entry is valid, it is removed.If the header contains a
fwd
entry, the intermediate system may introduce additionalvia
entries in the message path if appropriate. This allows routing to proceed even if the message sender does not know the complete route to the destination when sending the message.If the
path
header contains arev
element, the intermediate system may add a URI as its first child element to indicate a node on the reverse path for the message.The intermediate system uses the first
via
entry of thefwd
element as the URI for the next hop of the path. If there are no remainingvia
entries, the URI in theto
element is used instead. If there is noto
element, a fault is generated and returned to the sender.When the message reaches its intended recipient, it should validate that its own URI is either in the
to
element or in the only remainingvia
entry of thefwd
element. Failing this, a fault should be generated.
Should the receiver need to send a message back to the originator, it
again includes a path
header with
id
and action
elements,
together with a relatesTo
element whose value is
the URI from the id
element of the original
message. The to
, fwd
,
from
, and rev
elements may also
be included and are used as just described. If the original message
contains a rev
element, then its content
may be used to create the fwd
element of this message, but this is not mandatory.
For a definitive description of the message routing process, refer to the WS-Routing specification.
In order to create SOAP-RP messages, you need a
MessageFactory
that implements the SOAP-RP
profile. As described earlier, once you have a
ProviderConnection
for a provider that supports
this profile, you can obtain a suitable factory using the
createMessageFactory( )
method:
// Get a message factory for the SOAP-RP profile MessageFactory msgFactory = conn.createMessageFactory("soaprp");
To arrange for the correct factory to be used when receiving SOAP-RP
messages in the onMessage( )
method of
JAXMServlet
, you must override its init( )
method to install the same
MessageFactory
, as shown in Example 4-4.
All SOAP messages created using this factory are of type
com.sun.xml.messaging.soaprp.SOAPRPMessageImpl
.
They have a minimal path
header populated only
with empty fwd
and rev
elements.[46]
To include other elements or to add entries to the forward and
reverse paths, you need to use convenience methods provided by the
SOAPRPMessageImpl
class, definitions of which you
will find in the reference section of this book. A typical SOAP-RP
message header is shown in Example 4-7, earlier in
this chapter. The following sections cover some of the more important
aspects of this API.
The SOAP-RP
specification requires that each message has a unique identifier that
can be used to correlate it with either a fault or a reply.
Fortunately, you don’t have to generate these
identifiers for yourself, since one is automatically created each
time the factory returns a new SOAP-RP message. The
getSOAPRPMessageId( )
method can be used to
retrieve the identifier for a message. The most likely reason for
calling this method is to use its return value to set the value of
the relatesTo
element when building a fault or
reply message:
reply.setRelatesTo(request.getSOAPRPMessageId( ));
The API includes a method called newMessageId( )
that lets you set a new identifier for a message, but it is unlikely
that you will need to use this because it is called for you when a
SOAP-RP message is created.
The forward and
reverse message paths are held as Vector
s
containing Endpoint
objects. You can retrieve the
complete path and modify it directly using the
getSOAPRPFwdMessagePath( )
and getSOAPRPRevMessagePath( )
methods. There are also slightly more abstract methods
that let you update a path without having to fetch a complete copy of
it:
public void updateFwdMessagePath(Endpoint uri, int position); public void updateRevMessagePath(Endpoint uri);
The updateFwdMessagePath( )
method requires both the URI to be added
and the position in the path at which it is to be inserted, where the
value 0 indicates that the entry should be added at the front of the
list. The updateRevMessagePath( )
method does not
require a position index, since new elements in the reverse path are
always added at the start of the list.
If you need to create a reply or generate a fault for a message, you
might want to use the reverse path from the message as the forward
path for the reply or the fault. To do this, use the
getSOAPRPRevMessagePath( )
and
updateFwdMessagePath( )
methods together:
Vector revPath = soapMsg.getSOAPRPRevMessagePath( ); int count = revPath.size( ); for (int i = 0; i < count; i++) { replyMsg.updateFwdMessagePath((Endpoint)revPath.get(i), i); }
Warning
At the time of this writing, there is a problem with the reference
implementation of the SOAP-RP profile that causes the forward path to
be ignored. The specification requires that the to
element of the SOAP-RP header contains the URI of the final
destination and that the first via
child of the
fwd
element indicates the URI of the first
intermediate system. Unfortunately, the reference implementation
currently always sends the message to the system
whose URI is in the to
element, rather than using
the forward path, if there is one.
Fault
information is included using the fault
element,
which is a direct child of the path
header.
Unfortunately, the reference implementation does not provide any API
for accessing this information or creating it if it is not already
present. Therefore, if you want to add fault information to a new
message or extract it from a message that you have received, you must
do so by directly accessing the path
header, and
using the usual SAAJ APIs to add or locate the
fault
element. Here’s how you
might locate the path
header for a message:
final String SOAPRP_URI = "http://schemas.xmlsoap.org/rp";
message.addHeaders( );
SOAPHeader header = message.getSOAPPart().getEnvelope( ).getHeader( );
Iterator iter = header.getChildElements( );
while (iter.hasNext( )) {
SOAPElement elem = (SOAPElement)iter.next( );
Name name = elem.getElementName( );
// Compare both the local name and the namespace URI
if (name.getLocalName( ).equalsIgnoreCase("path") &&
name.getURI( ).equals(SOAPRP_URI)) {
// "elem" is the path header element.
}
}
When adding fault information to a newly created message, you should
call the addHeaders( )
method as shown in this
code extract before searching for the path
element, since the header is not actually created until this method
is invoked. This is not necessary in the case of a message received
in the onMessage( )
method of a servlet, since the
headers are created automatically as part of the process of
converting the received XML to a
SOAPMessage
.
[46] In fact, this is not a good default.
Ideally, fwd
and rev
elements
are added only when specifically requested, since the absence of the
rev
element has a specific meaning. With the
current implementation, it is not possible to create a
path
header without a rev
element. This may change in the future, of course.
Get Java Web Services in a Nutshell now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.