views:

1389

answers:

1

I have a class that implements the SOAPHandler interface. The handleMessage is defined as:

public boolean handleMessage(SOAPMessageContext context) {

  SOAPMessage msg = context.getMessage();
  SOAPPart part = msg.getSOAPPart();
  SOAPEnvelope envelope = part.getEnvelope();

  // add namespaces
  SOAPElement envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
  envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-      

  // add the header with additional elements
  Name qname = envelope.createName("Security", "sse", "http://example.com/security.xsd");
  element = envelope.addHeader().addChildElement(qname);

  qname = envelope.createName("mustUnderstand");
  element.addAttribute(qname, "1");

  qname = envelope.createName("UsernameToken", "sse", "http://example.com/user.xsd");
  element = envelope.getHeader().addHeaderElement(qname);
  element.addTextNode("user1");

  qname = envelope.createName("Password");
  element = envelope.getHeader().addHeaderElement(qname);
  element.addTextNode("1234");

}

} catch (Exception e) {
  e.printStackTrace();
}
  return true;
}

This generates the following message:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
  <S:Header>
    <sse:Security xmlns:sse="http://example.com/security.xsd" mustUnderstand="1"/>
    <sse:UsernameToken xmlns:sse="http://example.com/user.xsd"&gt;user1&lt;/sse:UsernameToken&gt;
  </S:Header>
  <S:Body>
    ....The rest of the transaction
  </S:Body>
</S:Envelope>

The problem is I need to generate a message with the following format:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
   <soapenv:Header>
      <sse:Security soapenv:mustUnderstand="1" xmlns:sse="http://example.com/security.xsd"&gt;
         <sse:UsernameToken wsu:Id="UsernameToken-9993341" xmlns:wsu="http://example.com/user.xsd"&gt;
            <sse:Username>user1</sse:Username>
            <sse:Password Type="http://example.com/password#PasswordText"&gt;1234&lt;/sse:Password&gt;
         </sse:UsernameToken>
      </sse:Security>
   </soapenv:Header>
  <soapenv:Body>
    ....The rest of the transaction
  </soapenv:Body>
</soapenv:Envelope>

The "mustUnderstand" attribute doesn't have the soapenv prefix, the sse:Security tag is closed right away instead of having the other tags as children, and the UserName isn't properly formatted as

<sse:Username>user1</sse:Username>

. How can I format the message properly using the SOAPElement methods? The biggest thing I need to know is how to properly next the tags inside of the Security tag and how to have the username/password tags properly formatted.

I've tried different combinations of the addHeaderElement and addChildElement methods, but I can't get it formatted properly and the javadocs don't give enough detail about what they will generate.

A: 

There's enough problems in this code that I'm thinking it's a troll, but heres a start:

The line :

element = envelope.addHeader().addChildElement(qname);

should read:

SOAPHeaderElement secHdrElement = envelope.addHeader().addHeaderElement(qname);

next, instead of:

qname = envelope.createName("mustUnderstand");
element.addAttribute(qname, "1");

probably:

secHdrElement.setMustUnderstand(true);

and

qname = envelope.createName("UsernameToken", "sse", "http://example.com/user.xsd");
element = envelope.getHeader().addHeaderElement(qname);
element.addTextNode("user1");

should be something like:

qname = envelope.createName("UsernameToken", "sse", "http://example.com/user.xsd");
element = secHdrElement.addHeaderElement(
          envelope.createName("UsernameToken", "sse", "http://example.com/user.xsd"));

and so on...

Bill Jones
This code isn't really different than what I had posted, and some of it won't even compile (like the setMustUnderstand). Can you explain how to add the Username and Password tags with the value inside the tags, not as an attribute?
Tai Squared
Tai - Regarding setMustUnderstand() - it's a method on SOAPHeaderElement (my example) but not on SOAPElement (your example), which is one of the differences in our code... Regarding creating proper DOM for the security header - in your code you first need to create a 'UserName' element as a child of 'UserNameToken', then you add a TextNode child to the UserName token. Likewise you will create a 'Password' element child of 'UserNameToken' and then add a text node to it. Hope this helps.
Bill Jones
btw, sorry for the really late reply. i need to turn on notifications...
Bill Jones