4

I am able to generate a SOAP message but I do not know

  • add prefix only to soapMessage tag (should not have namespace)

     SOAPConnectionFactory soapConnectionFactory =
                    SOAPConnectionFactory.newInstance();
     SOAPConnection connection =
                    soapConnectionFactory.createConnection();
     SOAPFactory soapFactory =
                    SOAPFactory.newInstance();
    
     MessageFactory factory =
                    MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
    
     SOAPMessage message = factory.createMessage();
     SOAPHeader header = message.getSOAPHeader();
     SOAPPart soapPart = message.getSOAPPart();
     SOAPEnvelope soapEnvelope = soapPart.getEnvelope();                
     SOAPBody body = soapEnvelope.getBody();
    
     soapEnvelope.removeNamespaceDeclaration(soapEnvelope.getPrefix());
     soapEnvelope.setPrefix("soap");
     body.setPrefix("soap");
    
     header.removeNamespaceDeclaration(header.getPrefix());
     header.setPrefix("soap");
    
     soapEnvelope.addNamespaceDeclaration("v9", "URL TO SERVER");
    
     Name bodyName;
     bodyName = soapFactory.createName("SearchHotels");
     SOAPBodyElement getList = body.addBodyElement(bodyName);
     getList.setPrefix("v9");
    
     Name childName = soapFactory.createName("SoapMessage", "v9", "URL TO SERVER");
     SOAPElement HotelListRequest = getList.addChildElement(childName);
    
     HotelListRequest.addChildElement("Hotel", "v9").addTextNode("Hilton");
    

My SOAP Message

   ...
     <v9:SoapMessage xmlns:els="URL TO SERVER">
         ...

What I expect

   ...
      <v9:SoapMessage>
           ...

Update :

If I use the following it runs into following error

    SOAPElement HotelListRequest = getList.addChildElement("v9:SoapMessage");

    org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a 
                                             way which is incorrect with regard to namespaces.
  • 1
    I am not sure for the empty header, but the from a semantical perspective both messages equal. The XML producer is allowed to make a late or just-in-time declaration of the namespace. Any parser should be able to live with both versions. – mwhs Nov 06 '13 at 22:19
  • @mwhs thanks, I could complete the last question but not the rest –  Nov 07 '13 at 09:04
  • What do you mean not the rest? – mwhs Nov 07 '13 at 09:06
  • 1
    @mwhs I mean how to add header to it, add namespace to all tags –  Nov 07 '13 at 09:08

2 Answers2

5

To add the namespace prefix to all the tags you have to redeclare the desired prefix (and eventually the namespace) on every inserted child, otherwise it will inherit the namespace (implicitely) from the parent element.

Try for instance:

SOAPBodyElement getList = body.addBodyElement(bodyName, "v9", "http://URL TO SERVER");

or

soapBody.addChildElement("SomeElement", "v9", "http://URL TO SERVER");

or

soapBody.addChildElement("v9:SomeElement");

Sometimes you may have to use a QName object instead of just a String or a Name.

It pretty much depends on the SOAP-API/Implementation you use, but the principle is the same everywhere: either redeclare (explicit) or inherit (implicit).

mwhs
  • 5,878
  • 2
  • 28
  • 34
  • 1
    Maybe use the method addHeader of the SOAPEnvelope object? – mwhs Nov 07 '13 at 09:23
  • 1
    I've used that before but accidentally removed it :( –  Nov 07 '13 at 09:31
  • 1
    thanks, I could change it, the only thing that I need is to add prefix to the following SoapMessage tag I would appreciate it if you could help me, Name bodyName; bodyName = soapFactory.createName("SearchHotels"); SOAPBodyElement getList = body.addBodyElement(bodyName); getList.setPrefix("v9"); Name childName = soapFactory.createName("SoapMessage"); SOAPElement HotelListRequest = getList.addChildElement(childName); –  Nov 07 '13 at 10:11
  • 1
    Use the version of createName which offers you to also pass a NS-prefix and the corresponding NS. See this link: http://docs.oracle.com/javaee/1.4/api/javax/xml/soap/SOAPFactory.html#createName%28java.lang.String,%20java.lang.String,%20java.lang.String%29 – mwhs Nov 07 '13 at 10:15
  • 1
    I've found that as well but the problem is that I do not want it to add namespace url, just need to have the prefix –  Nov 07 '13 at 10:19
  • 1
    once bounty is completed, please remind me to give you a bounty, for your help so far. –  Nov 07 '13 at 11:53
  • Ok, then you have to create the name like this: `soapBody.addChildElement("v9:SomeElement");` (answer updated) – mwhs Nov 07 '13 at 12:47
  • Did you declare the els namespace before? – mwhs Nov 07 '13 at 22:07
  • 1
    not sure what you mean by declaring, I just used the addnamespaceDeclaration for soapbody and updated the question with my latest code –  Nov 08 '13 at 12:34
  • 1
    Something like this: `soapEnvelope.addNamespaceDeclaration("els", "Namspace-URI");`? – mwhs Nov 08 '13 at 12:35
  • 1
    yes I have it as you see in the question. soapEnvelope.addNamespaceDeclaration("v9", "URL TO SERVER"); –  Nov 08 '13 at 12:52
  • In the question I only see "v9". – mwhs Nov 08 '13 at 12:53
  • 1
    let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/40819/discussion-between-alex-and-mwhs) –  Nov 08 '13 at 12:55
  • 1
    I need to wait 23 hours to award the bounty :D I have a new question please have a look at it thanks http://stackoverflow.com/questions/19953829/why-am-i-receiving-java-lang-nullpointerexception-rather-than-soap-response –  Nov 13 '13 at 12:30
-1

In your expected SOAP message there is a difference in case of prefix , seems you are writing client where requesting to a service provider which is developed in .net , this is why you may need to change prefix .

I think you can take concept from bellow code :

       MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); 
    SOAPMessage soapMessage = messageFactory.createMessage(); 

    SOAPPart soapPart = soapMessage.getSOAPPart(); 

    SOAPEnvelope soapEnvelope = soapPart.getEnvelope(); 

    SOAPBody soapBody = soapEnvelope.getBody(); 

    soapEnvelope.removeNamespaceDeclaration(soapEnvelope.getPrefix()); 
    soapEnvelope.addNamespaceDeclaration("soap", "http://schemas.xmlsoap.org/soap/envelope/"); 

    soapEnvelope.setPrefix("soap"); 
    soapBody.setPrefix("soap"); 

    soapEnvelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
    soapEnvelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");   soapMessage.getSOAPHeader().detachNode(); 

    soapMessage.getMimeHeaders().setHeader("SOAPAction", "http://www.example.com/TransactionProcess"); 

For more detail please visit this REFERENCE LINK

Asraful
  • 1,241
  • 18
  • 31
  • 1
    thanks , but could not figure out how to add the prefix to the tags, the one that you mention does not work, also now sure how to remove schemas..... namespace and also remove the namespace of searchHotels tag –  Nov 04 '13 at 12:23
  • 1
    @Alex please check the reference link there u will find the solution i checked just now – Asraful Nov 05 '13 at 09:17
  • i also face some integration problem while trying to write client for different payment gateway , where three way communication was involved - our system, gateway , and another thirdparty system of client -- in three case we had to sync the transaction information with retaining security and integrity , good luck – Asraful Nov 07 '13 at 09:08
  • 1
    thanks, but it is not about three way communication, I need to know how to add header to it, add namespace to all tags –  Nov 07 '13 at 09:10
  • if u want to build in body section with prefix and namespace , you can use manual process using StringBuilder -- though may be this is a temporary solution as i think , – Asraful Nov 07 '13 at 09:13