SAAJ Client

The Coffee Break server, which is a SAAJ client in this scenario, sends
requests to the SAAJ supplier. The SAAJ client application uses the SOAPConnection method call to send messages.

SOAPMessage response = con.call(request, endpoint);

Accordingly, the client code has two major tasks. The first is to create
and send the request; the second is to extract the content from the response.
These tasks are handled by the classes PriceListRequest and OrderRequest.

Sending the Request

This section covers the code for creating and sending the request for
an updated price list. This is done in the getPriceList method
of PriceListRequest, which follows the DTD price-list.dtd.

The getPriceList method begins by creating the connection
that will be used to send the request. Then it gets the default MessageFactory object to be used for creating the SOAPMessage object msg.

The next step is to access the message’s SOAPBody object,
to which the message’s content will be added.

SOAPBody body = msg.getSOAPBody();

The file price-list.dtd specifies that the topmost
element inside the body is request-prices and that it contains
the element request. The text node added to request is
the text of the request being sent. Every new element that is added to the
message must have a QName object to identify it. The following
lines of code create the top-level element in the SOAPBody object body. The first element created in a SOAPBody object
is always a SOAPBodyElement object.

In the next few lines, the code adds the element request to
the element request-prices (represented by the SOAPBodyElementrequestPrices). Then the code adds a text node
containing the text of the request. Next, because there are no other elements
in the request, the code calls the method saveChanges on
the message to save what has been done.

With the creation of the request message completed, the code sends the
message to the SAAJ coffee supplier. The message being sent is the SOAPMessage object msg, to which the elements created in
the previous code snippets were added. The endpoint is the URI for the SAAJ
coffee supplier, http://localhost:8080/saaj-coffee-supplier/getPriceList. The SOAPConnection object con is
used to send the message, and because it is no longer needed, it is closed.

When the call method is executed, the Application
Server executes the servlet PriceListServlet. This servlet
creates and returns a SOAPMessage object whose content
is the SAAJ supplier’s price list. (PriceListServlet is
discussed in Returning the Price List.) The
Application Server knows to execute PriceListServlet because
the given endpoint is mapped to that servlet.

Extracting the Price List

This section demonstrates (1) retrieving the price list that is contained
in response, the SOAPMessage object
returned by the method call, and (2) returning the price
list as a PriceListBean.

The code creates an empty Vector object that will
hold the coffee-name and price elements
that are extracted from response. Then the code uses response to access its SOAPBody object, which
holds the message’s content.

The next step is to retrieve the SOAPBodyElement object.
The method getChildElements returns an Iterator object
that contains all the child elements of the element on which it is called,
so in the following lines of code, it1 contains the SOAPBodyElement object bodyEl, which represents the price-list element.

The Iterator object it2 holds
the child elements of bodyEl, which represent coffee elements.
Calling the method next on it2 retrieves
the first coffee element in bodyEl. As long as it2 has
another element, the method next will return the next coffee element.

The next lines of code drill down another level to retrieve the coffee-name and price elements contained in it3.
Then the message getValue retrieves the text (a coffee
name or a price) that the SAAJ coffee supplier added to the coffee-name and price elements when it gave content to response.
The final line in the following code fragment adds the coffee name or price
to the Vector object list. Note that
because of the nested while loops, for each coffee element
that the code retrieves, both of its child elements (the coffee-name and price elements) are retrieved.

The final code fragment adds the coffee names and their prices (as a PriceListItem) to the ArrayListpriceItems,
and prints each pair on a separate line. Finally it constructs and returns
a PriceListBean.

Ordering Coffee

The other kind of message that the Coffee Break servers can send to
the SAAJ supplier is an order for coffee. This is done in the placeOrder method of OrderRequest, which follows the DTD coffee-order.dtd.

Creating the Order

As with the client code for requesting a price list, the placeOrder method starts by creating a SOAPConnection object
and a SOAPMessage object and accessing the message’s SOAPBody object.

Because the given endpoint is mapped to ConfirmationServlet,
the Application Server executes that servlet (discussed in Returning the Order Confirmation) to create and
return the SOAPMessage object reply.

Retrieving the Order Confirmation

The rest of the placeOrder method retrieves the information
returned in reply. The client knows what elements are in
it because they are specified in confirm.dtd. After accessing
the SOAPBody object, the code retrieves the confirmation element and gets the text of the orderID and ship-date elements. Finally, it constructs and returns a ConfirmationBean with this information.