Convincing JAX-WS on Axis2 1.4 to handle overloaded web service methods
Posted by Akom • Saturday, August 16. 2008 • Category: JavaThis week I found myself in one of those situations...
I had initially implemented corporate web services in Axis2 1.2, using ADB data binding, starting with a WSDL. Only problem is - the WSDL I had to reimplement came from .NET, sometime around 2001... when overloading must have seemed like a good idea. Since then it's been abolished by just about everyone, including of course the current WSDL specifications. Moreover, the WSDL was most likely auto-generated by .NET with no regard for how manageable it would be. Yes, this is an experience infused with "ArrayOfAnyType", <anytype xsd:type="string">, and other such pearls.
I can't say that ADB handled overloaded methods
too well, but with the ability to hack up my auto-generated Message Receiver any way I wanted - I could easily customize behaviour depending on the incoming action.
But I wanted to get away from the ADB hell of insane data structures, pull parsers and a whole slew of other acronyms that were just ... well, cumbersome. Maybe I just don't understand the beauty of the whole thing, but JAX-WS was sounding better and better, reviews raving about it and it promising nice, clean, annotated style of implementation. So I plunged in.
Axis2 now supports JAX-WS, and I had written some interesting cross-service/cross-module containers for statistics reporting and various cached DB resources that I wanted to continue to use... not to mention various JSP's I hacked in to AXIS's own axis2-web directory in my packaging steps... So I decided to go with axis2+jax-ws.
To make a long story short:
- I used wsimport without issues and it produced very clean annotated beans and an interface for me to implement, with both signatures for my overloaded methods.
- I eventually got it up and running, and soon was greeted with an "overloaded methods are not supported" message. Bummer.
I was determined. I wanted JAX-WS in axis2.
I set up the entire code base in Eclipse and stepped through the execution. Eventually I landed in the Utils class, staring at the following code:
modules/jaxws/src/org/apache/axis2/jaxws/server/endpoint/Utils.java
167 OperationDescription[] ops = eid.getDispatchableOperation(mc.getOperationName()); 168 // TODO: Implement signature matching. Currently only matching on the wsdl:OperationName is supported. 169 // That means that overloading of wsdl operations is not supported (although that's not supported in 170 // WSDL 1.1 anyway). 171 if (ops == null || ops.length == 0) { 172 throw ExceptionFactory.makeWebServiceException( 173 Messages.getMessage("oprDescrErr",mc.getOperationName().toString())); 174 } 175 if (ops.length > 1) { 176 throw ExceptionFactory.makeWebServiceException( 177 Messages.getMessage("oprDescrErr1",mc.getOperationName().toString())); 178 }
After some thinking about possible ways to inject modifications to this method from my own code, I surrendered to the hacky approach as the most efficient, and came up with the following revisions:
167 168 OperationDescription[] ops = eid.getDispatchableOperation(mc.getOperationName()); 169 // TODO: Implement signature matching. Currently only matching on the wsdl:OperationName is supported. 170 // That means that overloading of wsdl operations is not supported (although that's not supported in 171 // WSDL 1.1 anyway). 172 if (ops == null || ops.length == 0) { 173 throw ExceptionFactory.makeWebServiceException( 174 Messages.getMessage("oprDescrErr",mc.getOperationName().toString())); 175 } 176 if (ops.length > 1) { 177 String requestAction = mc.getAxisMessageContext().getOptions().getAction(); 178 OperationDescription found = null; 179 for (int i = 0; found == null && i < ops.length; i++) { 180 if (ops[i] instanceof OperationDescriptionJava) { 181 String webMethodAction = ((OperationDescriptionJava)ops[i]).getAnnoWebMethodAction(); 182 if (requestAction != null && webMethodAction != null && requestAction.equals(webMethodAction)) { 183 //return this one 184 found = ops[i]; 185 } 186 } 187 } 188 189 if (found == null) { 190 throw ExceptionFactory.makeWebServiceException( 191 Messages.getMessage("oprDescrErr1",mc.getOperationName().toString())); 192 } 193 ops = new OperationDescription[] {found}; 194 } 195 op = ops[0];
Download file: Utils.java
So now I am assuming that we are in java here (hmm), and assuming that the client is sending the Action through, either in header or however else. This actually works. Well at least in my testing it does.
0 Comments
Add Comment