tags:

views:

31

answers:

0

Hello there,

I have an interesting issue in a jax-ws client generated with wsimport tool and using a SOAPHandler to intercept the message before it goes out. I need to omit the xml declaration, since the web service is out of my control and throws a fault if there is an xml declaration, I have been trying all sorts of variations, including

1) Setting the javax.xml.soap.write-xml-declaration system property to "false" 2) Changing the mime headers of soap message, soap part etc 3) Using @BindingType(HTTPBinding.HTTP_BINDING) annotation on the service and PortType classes

The only solution that seems to work is to use the SAAJ SOAPConnectionFactory and send the intercepted message through that, but that's not really a good solution at all, since I will have to then unmarshall the reply manually from xml to a Java object, which will defeat the purpose behind jaxb and jax-ws.

I found another post related to axis, but what it says there about omitting xml declaration is discouraging in my case:

[https://issues.apache.org/jira/browse/AXIS-1518][1]

This is an excerpt from that forum:

This is a patch for xml declaration. A short description is :

  • mixing SOAPPart approach and SerializationContext and SAXOutputter approach. SOAPPart : determine xml decl is needed (using currently added currentEncoding) SerializaitonContext and SAXOutputer : output xml decl
  • JAX-RPC view : When there is a MessageContext, xml decl is always emitted. (This is necessary. Isn't it?)
  • SAAJ view : When there is no MessageContext, xml decl is emitted according to SOAPMessage.WRITE_XML_DECLARATION property

    - Additional Fix : SOAPMessage.CHARACTER_SET_ENCODING property works now.

I have code like this on my side...

using JAX-WS RI 2.2.1-b01

... public class SoapLoggingHandler implements SOAPHandler { ...

public boolean handleMessage (SOAPMessageContext messageContext) { SOAPMessage soapMsg = messageContext.getMessage();

boolean request = ((Boolean) messageContext.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();

   SOAPConnectionFactory soapConnFactory = null;
   SOAPConnection connection = null;
   SOAPMessage reply;

try {
   if (request) { // This is a request message.

    SOAPEnvelope envelope = messageContext.getMessage().getSOAPPart().getEnvelope();
    SOAPHeader header = envelope.addHeader(); //adding an empty header

                            //SOAPConnectionFactory by default does not emit the xml declaration
                            //But then I will have to look through the xml tree in the reply to get my object's values
                            //which is defeating the whole purpose behind jax-ws and specifically jaxb

    soapConnFactory = SOAPConnectionFactory.newInstance();
    connection = soapConnFactory.createConnection();

                            //Setting WRITE_XML_DECLARATION to "false" below does not work!!! 
                           //the xml declaration is still emitted

    soapMsg.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "false");
    messageContext.setScope(SOAPMessage.WRITE_XML_DECLARATION, Scope.APPLICATION);
    soapMsg.saveChanges();

       soapMsg.writeTo (outputStream);

       reply = connection.call(soapMsg, "http://endpointurl/endpoint");
   }
   else { // This is the response message 
      soapMsg.writeTo (outputStream);
   }
   System.out.println("\n\n");
}
catch (Exception e) { 
 e.printStackTrace(); 
}
finally {
 if(connection!=null) {
   try {
     connection.close();
   } catch (SOAPException e) {
     e.printStackTrace();
   }
  }
 }
 //return false; //when using SOAPConnectionFactory since JAX-WS request not needed anymore
 return true;
}

Any help would be greatly appreciated, minister