Helping ordinary people create extraordinary websites!
HOME TUTORIALS SCRIPTS WEB HOSTING BLOG FORUM
Get Our Newsletter
Email:

Better SOAP Interfaces With Header Elements

By Benoit Marchal
2004-01-26


Header elements in AXIS

Handlers


For simplicity, I chose to process the header in the server itself. AXIS
offers a more flexible alternative through handlers. A handler processes
certain header elements on behalf of the server, and the coding is very
similar.

To illustrate how to implement header extensions, I'll use AXIS, the Apache SOAP toolkit. The sample service is trivial: It adds up two integers. The service interface has only one method, add(), which takes two integers as parameters.

Imagine that the server can prioritize requests: High priority requests will get a faster answer than low priority ones. How do you extend the service interface? While you could extend the add() method with a third priority parameter, it's not a good idea, primarily because doing so breaks existing clients and servers. In addition, it pollutes the interface with a technical parameter. Not every server is able to honour the priority, and not every client has a notion of priority. A better solution is to move the technical parameter to the header, where it belongs.

Listing 1 is a SOAP server that recognizes a priority header element. The service uses the MessageContext object to retrieve an instance of a Message object that represents the request. Next, it searches for a priority element in the header. The service sleeps for more or less time, depending on the priority (sleeping emulates low priority requests in this example). Note that the service accepts requests with no priority. Finally it sets the processed flag so AXIS knows the element has been dealt with (this flag is essential if the element has a mustUnderstand attribute). The server is compatible with those clients that do not implement the priority mechanism.

Listing 1. A server processes a header extension


import java.util.*;
import org.apache.axis.*;
import org.apache.axis.message.*;

public class HeaderService
{
public int add(int op1, int op2)
throws Exception
{
MessageContext context = MessageContext.getCurrentContext();
Message message = context.getRequestMessage();
SOAPEnvelope envelope = message.getSOAPEnvelope();
SOAPHeaderElement element =
envelope.getHeaderByName("http://psol.com/2003/tips/header",
"priority");
if(element != null)
{
Integer priority =
(Integer)element.getValueAsType(Constants.XSD_INT);
// lower priority requests are delayed to simulate priorities
switch(priority.intValue())
{
case 0:
Thread.sleep(40000);
break;
case 1:
Thread.sleep(30000);
break;
case 2:
Thread.sleep(20000);
break;
case 3:
Thread.sleep(10000);
break;
case 4:
Thread.sleep(5000);
break;
default:
// top speed, no sleeping
break;
}
element.setProcessed(true);
}
else
// unless the service requests a priority, it runs very low
Thread.sleep(50000);
return op1 + op2;
}
}


Listing 2 is the client. If a priority argument is in the command line, it creates a SOAPHeaderElement object and passes it to the Call object. Again, this client is compatible with servers that do not implement the priority mechanism.

Listing 2. Corresponding client


import java.net.*;
import org.apache.axis.client.*;
import org.apache.axis.message.*;
import org.apache.axis.encoding.*;
import javax.xml.rpc.ParameterMode;

public class HeaderClient
{
public static void main(String [] args)
{
if(args.length < 2)
{
System.out.println("HeaderClient op1 op2 [-priority:0-5]");
return;
}
try
{
Integer op1 = new Integer(args[0]),
op2 = new Integer(args[1]);
URL endpoint =
new URL("http://localhost:8080/axis/HeaderService.jws");
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(endpoint);
call.setOperationName("add");
call.addParameter("op1",XMLType.XSD_INT,ParameterMode.IN);
call.addParameter("op2",XMLType.XSD_INT,ParameterMode.IN);
call.setReturnType(XMLType.XSD_INT);
if(args.length > 2 && args[2].startsWith("-priority:"))
{
Integer priority = new Integer(args[2].substring(10));
if(priority.intValue() < 0 || priority.intValue() > 5)
priority = new Integer(3);
SOAPHeaderElement element =
new SOAPHeaderElement("http://psol.com/2003/tips/header",
"priority");
element.setObjectValue(priority);
call.addHeader(element);
System.out.println("Request priority = " + priority);
}
else
System.out.println("No priority set for request");
Integer result = (Integer)call.invoke(new Object[] { op1, op2 });
System.out.println(op1 + " + " + op2 + " = " + result);
}
catch (Exception x)
{
System.err.println(x.toString());
}
}
}



Tutorial Pages:
» Header elements and the AXIS toolkit
» Intranet and Internet services
» Header elements in AXIS
» Conclusion
» Resources


First published by IBM developerWorks


 | Bookmark
Related Tutorials:
» Starting with XML
» Performing Client-Side XSL Transformations
» Create a Google Sitemap for your Web Site
» XML and Scripting Languages
» Parsing Comma-Separated Values
» XML Security Suite: Increasing the Security of E-Business