In particular, during a recent project I stumbled across the part of the Spring manual that described how to set up a JAX-RPC proxy using CGIlib and a thin spring wrapper (the JaxRpcPortProxyFactoryBean class). I thought "hey I will give it a go" and in typical Spring fashion in perhaps 5 minutes I had a small test working that hit a very simple web service.
Adventures in Shirking My Work
With that encouraging result I turned my attention to the web service I was building at the time. The XML schema for this web service ran to several hundred lines, with a couple of dozen types including polymorphism and enumerations. The Spring JAX-RPC proxy had a simple method for specifying the XML-java mappings and I mentally cringed but started grunting my way through the glue code I needed to generate. I didn't get far - I just have never been good at menial tasks (some people would say that about my ability to do just about any task, but lets not go there, shall we?)
In an effort to avoid real work I started poking around in Spring source code, and it wasn't too long before I discovered that Spring uses the Axis JAX-RPC client to provide client-side web service connectivity. Hmmm.... I thought. I was already using Axis to serve my web service,
and I had managed to completely describe the Object-XML mappings in the Axis deployment description (WSDD file). It made me start to wonder - could I use the same type mappings for the Spring JAX-RPC client?
Working Hard to avoid Working Hard
There was a post-processing method on the JaxRpcPortProxyFactoryBean where the type mapping information could be loaded, and after a little experimentation I finally came up with:
protected void postProcessJaxRpcService(javax.xml.rpc.Service service){
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
try
{
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(
new ClassPathResource(classpathAccessibleWSDDFile).getInputStream());
WSDDService wsddService =
new WSDDDocument(document).getDeployment().
getWSDDService(new QName(wsddServiceName));
if ( wsddService == null )
throw new RuntimeException("No WSDD Service named \""+wsddServiceName+"\" was available");
TypeMapping serviceTypeMappings = wsddService.getTypeMapping(SOAP_ENCODING_STYLE);
TypeMappingRegistry registry = service.getTypeMappingRegistry();
registry.register(SOAP_ENCODING_STYLE, serviceTypeMappings);
}
catch (Exception e)
{
throw new RuntimeException("failed", e);
}
}
Waiting for the Flash to Hit Me
I was feeling pretty cheeky for the rest of the day, having managed to add a sophisticated JAG-RPC client to my arsenal with only a couple of lines of code. It wasn't till a couple of weeks later when I was about to add a second client (to a different web service) that I really realized how quickly I could put together just about any client from a valid WSDL file and a WSDD deployment descriptor.
I have 4 or 5 working clients now, including both RPC style and Document style web services. And all as a result of feeling too lazy one day to do my real job.
Is there a lesson there? Not one I would tell my kids.

1 comment:
Thank you. It really helped.
Post a Comment