ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Developing E-Business Interactions with JAXM

by Nikhil Patil
04/30/2003

JAXM, the Java API for XML Messaging, defines a lightweight Java API for composing, processing, sending, and receiving XML documents. The goal of JAXM is to provide a rich set of interfaces for document-style web services. Document-style web services enable the exchange of XML documents between two parties, as opposed to RPC-style web services, which expose software functions as web services. JAXM-based web services can be used effectively in the following scenarios:

  • When interactions between two parties are asynchronous in nature. JAXM provides support for both synchronous and asynchronous exchange of XML documents.

  • When two parties want to exchange data using XML documents that are bounded using well-defined XML schemas instead of invoking software functions (Java objects, C procedures, etc.) exposed as RPC-style web services.

Consider, for example, Argon Copiers. Argon has developed an application called Argon Service Center (ASC) which allows their field service technicians to charge Argon's customers using wireless PDAs (Figure 1). The wireless PDA interacts with Argon's invoice-processing system through a web application. The interaction between the PDA and the Argon web application is synchronous in nature. On receiving the invoice, the invoice-processing system performs a series of operations (e.g., getting customer information from the ERP system) that can take a considerable amount of time. To improve user experience by reducing response times, an interaction like the one between the web application and the invoice-processing system can be modeled as an asynchronous interaction. In this article, we use the example of Argon to learn how to use JAXM for building applications based on document-style web services.

Download the source code for this example.

Argon architecture
Figure 1. Argon architecture

JAXM Basics

Figure 2 illustrates the fundamental elements of the JAXM architecture.

JAXM architecture
Figure 2. JAXM architecture

The JAXM Service

A JAXM service consumes JAXM messages sent by a JAXM client. To develop a JAXM service, developers extend the class javax.xml.messaging.JAXMServlet and implement either the javax.xml.messaging.OnewayListener or javax.xml.messaging.ReqRespListener interface. The choice of interface depends upon whether the interaction between the client and the server is asynchronous (OnewayListener) or synchronous (ReqRespListener) in nature.

Related Reading

Java & XML Data Binding
By Brett McLaughlin

The JAXM Client

Clients exchange messages with JAXM services. JAXM clients can either interact directly with a JAXM service or go through a JAXM provider. JAXM clients that interact directly with a JAXM service can only participate in synchronous interactions. JAXM clients that use a messaging provider can participate in asynchronous as well as synchronous interactions with the JAXM service.

The JAXM Messaging Provider

A JAXM messaging provider is responsible for managing the routing of messages for a JAXM client. Besides providing a degree of separation between a JAXM client and service, a provider can also offer additional services like reliable messaging, security, and transaction support. Currently, clients that want to interact asynchronously with a JAXM service have to use a provider.

The JAXM Message

All JAXM messages conform to the SOAP 1.1 and SOAP with Attachments standards. JAXM messages also support the concept of higher-level protocols like ebXML through the concept of messaging profiles. A messaging profile defines the messaging contract between two parties. A JAXM client and service that share a message profile like ebXML can conduct business by exchanging ebXML messages.

Developing Asynchronous Interactions

JAXM clients that want to interact asynchronously with a JAXM service have to use a messaging provider, and must run in a servlet container or an EJB container as a message-driven bean. This restriction allows the messaging provider to notify the client when the JAXM service has finished processing its request.

In our example, the Dispatcher servlet (argon.Dispatcher) is a JAXM client that asynchronously exchanges invoice information with the invoice-processing system (Figure 3) through a JAXM service (argon.InvoicingServlet).

asynchronous JAXM service
Figure 3. Asynchronous JAXM service

The Dispatcher servlet creates a connection to a JAXM provider during initialization, as shown below.

try
{
    connectionFactory = ProviderConnectionFactory.newInstance();
    connection        = connectionFactory.createConnection();
}
catch (SOAPException e)
{
    throw new ServletException(e);
}

The Dispatcher servlet uses the default implementation of the JAXM provider that is bundled with the JAXM reference implementation. Clients can also retrieve JAXM providers that are bound to a JNDI context.

Before sending a message, the Dispatcher servlet selects a JAXM profile that is supported by the provider. A list of supported profiles is available in the ProviderMetaData class instance returned from the getMetaData method on the ProviderConnection class:

String[] supportedProfiles = metaData.getSupportedProfiles();
String profile = null;
for(int i=0; i < supportedProfiles.length; i++)
{
    if(supportedProfiles[i].equals("soaprp"))
    {
        profile = supportedProfiles[i];
        break;
    } 
}

In Argon's case, the Dispatcher servlet uses the SOAP-RP profile provided by the reference implementation. SOAP-RP provides an implementation of the Web Services Routing Protocol that supports messaging between applications through an intermediary, like a JAXM provider.

Next, the Dispatcher servlet uses a custom MessageFactory to create a message that supports the SOAP-RP profile.

SOAP-RPMessageImpl msg = (SOAP-RPMessageImpl)mf.createMessage();

After adding the necessary elements to the message body (see Listing 1), the Dispatcher servlet invokes the send method on the ProviderConnection. The underlying XML message sent by the client is shown in Listing 2.

The send method assumes a one-way asynchronous communication between the client and the service. Invoking send by itself doesn't guarantee successful delivery of the message to the JAXM provider. The underlying JAXM provider implementation is responsible for delivering the message successfully to the JAXM Service.

The JAXM messaging provider asynchronously routes the SOAP message to the JAXM service implemented by the class argon.InvoicingServlet. On receiving the message, the JAXM service extracts information about the invoice from the message, as shown in Listing 3. This information is then passed on to the invoice-processing system. Note that since this is an asynchronous interaction, the JAXM service doesn't return any response.

Developing Synchronous Interactions

Although synchronous interactions are typically thought of as being synonymous with RPC-style web services, there are situations where document-based web services make a better case for synchronous exchange of documents. Take the example of two parties that want to exchange ebXML documents: an RPC-style web service that exposes a system's object model through WSDL may not be capable of exchanging ebXML documents, whereas a document-based JAXM service — which is not bound to by an object model — can easily lend itself to this situation.

In our example, field technicians can use Argon's web application to search for invoices by client names (Figure 4). The Dispatcher servlet (JAXM client) conducts the search on behalf of the technician through a synchronous message exchange with a JAXM service (argon.InvoiceInfoServlet).

searching via the web app
Figure 4. Searching via the web app

The Dispatcher servlet uses the default MessageFactory class to create an empty SOAPMessage and then populates the SOAP message body with required elements, as shown in Listing 1.

After constructing the message, the Dispatcher servlet uses the javax.xml.soap.SOAPConnectionFactory class to create a connection and send the message, as shown below.

SOAPConnection connection = 
    SOAPConnectionFactory.newInstance().createConnection();
java.net.URL endpoint =
    new java.net.URL("http://localhost:8080/argon/findInvoices");
// Send the message
SOAPMessage responseMessage = connection.call(message, endpoint);

Note the difference between the call method of the SOAPConnection class and the send (Listing 1) method of the ProviderConnection class. The call method accepts an instance of java.net.URL, which directly points to the JAXM service. The send method of the ProviderConnection class assumes that the address of the JAXM service is embedded in the SOAP message. The call method also blocks the JAXM client until the JAXM service returns a response.

The message is directly routed to the JAXM service implemented by the servlet argon.InvoiceInfoServlet. This servlet extends the class JAXMServlet and implements the ReqRespListener interface. As shown in Listing 4, the InvoiceInfoServlet extracts the search criteria from the incoming SOAP message, searches the invoice processing system, and returns a SOAP message containing the search results to the JAXM client.

Conclusion

JAXM provides a good starting point for developing document-style web services that can promote the exchange of information between enterprises in a loosely coupled fashion through context-sensitive documents. Using JAXM, developers can build applications that are a combination of synchronous and asynchronous interactions.

References

  1. Sun's JAXM web site
  2. Web Services Routing Protocol

Nikhil Patil is Sun Certified Java Developer and a Product Manager at Cysive, Inc.


Return to ONJava.com.