1.8. JAX-RPC client-side handler

1.8.1. View the SOAP message using a handler.

Let's see now how to create and register a JAX-RPC handler. This handler will be executed each time a SOAP message is send or received by your client. The purpose of this first example is to show how to trace the SOAP message using javax.xml.transform for the response message. Find below the code for the handler, we will see after how to register it.

1.8.2. Modify the SOAP message using DOM from inside a handler.

If we have to modify the SOAP message returned by the web service (e.i.: to match a specific deserializer), we could need to use the DOM to change or to add some attributes.

Example 1-17. AdapterHandler.java

We are going to use the DOM to add an attribute to the return soap message (the response soap message received by our client). We also echo the modified SOAP message before to process it by our client.


package rcxwsclient;

import javax.xml.rpc.handler.*;

import javax.xml.namespace.QName;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.rpc.JAXRPCException;
import javax.xml.rpc.NamespaceConstants;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPBody;
import org.w3c.dom.*;

import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Source;

import javax.xml.transform.stream.StreamResult;

public class AdapterHandler extends GenericHandler {
	
  HandlerInfo hi;
	
  public void init(HandlerInfo info) {
    hi = info;
  }

  public QName[] getHeaders() {
    return hi.getHeaders();
  }

  public boolean handleResponse(MessageContext context) {

  System.out.println( "response");

  try {

    // get the soap header
    SOAPMessageContext smc = (SOAPMessageContext) context;
    SOAPMessage message = smc.getMessage();

    SOAPBody sb = message.getSOAPBody();

    // We expect only one tag <Result> in our SOAP response
    // message but I will use a "for" loop just in case...
    NodeList nl = sb.getElementsByTagName("Result");
				
    for(int x=0; x < nl.getLength(); x++) {
     
      int nnml = nl.item(x).getAttributes().getLength();
      NamedNodeMap nnm = nl.item(x).getAttributes();
      Document doc = nl.item(x).getOwnerDocument();
      // the attribute name and value added
      // are just here for demo
      Attr myattr = doc.createAttribute("xmlns:myref");
      myattr.setValue("urn:www.pascalbotte.be");
      
      Node newN = myattr.cloneNode(false);
     
      nnm.setNamedItem(newN);
      					
      System.out.println("node name: " + nl.item(x).getNodeName() + "\n");
      
      for(int y=0; y < nnml; y++){
	Node n = nl.item(x).getAttributes().item(y);
	System.out.println("\tattribute name: " + n.getNodeName() + ", value: " + 
	  n.getNodeValue() + "\n");
      }
    }
	    
    // Create transformer
    TransformerFactory tff = TransformerFactory.newInstance();
    Transformer tf = tff.newTransformer();

    // Get reply content
    Source sc = message.getSOAPPart().getContent();

    // Set output transformation
    StreamResult result = new StreamResult(System.out);
    tf.transform(sc, result);
    System.out.println();            
    } catch (Exception e) {
      throw new JAXRPCException(e);
    }
    return true;
  }

  public boolean handleRequest(MessageContext context) {

    // return true to continue message processing
    return true;
  }
}

1.8.3. Register a JAX-RPC client handler.

Now we have to register one of the above handler to complete the demo. In this case I will use my JAX-RPC/AXIS simple client. I list below the code for the simple readLS() remote procedure for my JWSDP web service (rpc/encoded version).

You can refer eventually to the Section called Use AXIS and JAX-RPC to create a SOAP client with WSDL2Java (for rpc encoded or document literal operation style) to use the AXIS tool: WSDL2Java for the service endpoint interface generation class (in this case the RcxReadLS class).