Hi I am trying to create a simple handler which alters the content of the SOPABody of an incoming SOAP message.
The web service I am using is a simple "echo" web service with a single method called echo. The methods takes a string and just returns it. The code for the handler is as follows: package com.trifork.eas.test.webservices.echoservice; import java.io.*; import java.io.InputStream; import java.util.*; import java.util.Iterator; import javax.xml.namespace.QName; import javax.xml.rpc.handler.*; import javax.xml.rpc.handler.soap.SOAPMessageContext; import javax.xml.soap.*; import javax.xml.soap.SOAPMessage; import javax.xml.transform.stream.*; /** * Created: Jan 20, 2003 * * @author Claus Nyhus Christensen <[EMAIL PROTECTED]> */ public class EchoServiceServerHandler implements Handler { public boolean handleRequest(MessageContext messageContext) { try { SOAPMessageContext soapMsgCtx = (SOAPMessageContext) messageContext; SOAPMessage soapMsg = soapMsgCtx.getMessage(); SOAPPart soapPart = soapMsg.getSOAPPart(); SOAPEnvelope soapEnvelope = soapPart.getEnvelope(); soapEnvelope.getBody().detachNode(); SOAPBody soapBody = soapEnvelope.addBody(); SOAPBodyElement echoElement = soapBody.addBodyElement(soapEnvelope.createName("echo", "ns1", "http://soapinterop.org/")); SOAPElement argElement = echoElement.addChildElement("arg0"); argElement = argElement.addAttribute(soapEnvelope.createName("type", "xsi", "http://www.w3.org/2001/XMLSchema-instance"), "xsd:string"); argElement.addTextNode("a new string"); soapMsg.saveChanges(); } catch (Exception e) { e.printStackTrace(); } return true; } ... } Now, when my client tries to call the web service, I get the following exception: AxisFault faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException faultSubcode: faultString: java.lang.Exception: No deserialization context to use in MessageElement.getValueAsType()! faultActor: null faultNode: null faultDetail: stackTrace: java.lang.Exception: No deserialization context to use in MessageElement.getValueAsType()! at org.apache.axis.message.MessageElement.getValueAsType(MessageElement.java:544) at org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider.java:150) at org.apache.axis.providers.java.JavaProvider.invoke(JavaProvider.java:332) at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:71) at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:156) at org.apache.axis.SimpleChain.invoke(SimpleChain.java:126) at org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService.java:469) at org.apache.axis.server.AxisServer.invoke(AxisServer.java:326) at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:782) .... I have been looking into the code, and it seems that the way the original SOAPBody is build is different from the way it is done when you use the JAXM methods on the SOAPBody class. I have tried the same example using the JAXRPC/SAAJ reference implementations and it works just fine there. To me it seems that: 1. I am doing something completely wrong in my handler or 2. The addBodyElement on the SOAPBody class is not working as is should If you agree with me that number 2 is the case, I would like to help create a fix. But I cannot figure out how I am going to be able to get a DeserializationContext in the SOAPBody class. A related problem occur if you use the addChildElement on SOAPBody instead of addBodyElement. When you do this a new MessageElement is added to the SOAPBody. However, this will result in a ClassCastException in the processMessage of the RPCProvider class. Line 141 and 142 gives the problem: if (!(bodies.get(bNum) instanceof RPCElement)) { SOAPBodyElement bodyEl = (SOAPBodyElement)bodies.get(bNum); Since the MessageElement is not an instance of RPCElement, it is cast to a SOAPBodyElement. This will result in the ClassCastException. This case also works fine on the JAXRPC/SAAJ reference implementation. The fix seems to be to overwrite the addChildElement methods in SOAPBody (which it inherits from MessageElement) to make sure that SOAPBodyElements (or maybe RPCElement) are always added. However, this fix will have the same problem with the DeserializationContext as stated above. I hope this mail was not to long, and was posted to the right mailinglist :) Cheers -- Claus Nyhus Christensen Software Engineer, M. Sc. CS. Trifork, Margrethepladsen 3, DK-8000 ?rhus C, Denmark Phone: +45 8732 8787 / Fax: +45 8732 8788 / http://www.trifork.com