views:

8129

answers:

3

A typical SOAP client request using JAX-WS might be

FooService service = new FooService();
FooPort port = service.getFooPort();
FooPayload payload = new FooPayload();
payload.setHatSize(3);
payload.setAlias("The Hat");
...
port.processRequest(payload);

This generates an HTTP request content something like

<?xml ... ?>
<S:Envelope xmlns:S="http://...soap-envelope"&gt;
  <S:Body>
    <!-- payload -->
  </S:Body>
</S:Envelope>

By manipulating the arguments to the port.processRequest() call you can only affect the "payload" part. You can't affect the outer part of the XML message.

I want to insert a SOAP header just before the SOAP Body

<S:Header>
   <X:Security xmlns:X="http://...wsssecurity...&gt;
      <X:BinarySecurityToken>kjh...897=</X:BinarySecurityToken>
   </X:Security>
</S:Header>

How do I do that?

A: 

you might want to look at handlers and handler chains.- I recently had to add a cookie to a given Webservice call and that was how i did it, just created a handler that intercepted the initial call and injected the cookie, you can also manipulate the call headers with a Pivot Handler

Nuno Furtado
+2  A: 

Thanks Nuno,

Just as soon as I work out how to log in properly to stackoverflow.com I'll do the right thing with your reply.

In the mean time here's the code I ended up with:

FooService service = new FooService();
service.setHandlerResolver(new HandlerResolver() {
    public List<Handler> getHandlerChain(PortInfo portInfo) {
        List<Handler> handlerList = new ArrayList<Handler>();
        handlerList.add(new RGBSOAPHandler());
        return handlerList;
    }
});
FooPort port = service.getFooPort();
FooPayload payload = new FooPayload();
payload.setHatSize(3);
payload.setAlias("The Hat");
...
port.processRequest(payload);

and

class RGBSOAPHandler implements SOAPHandler<SOAPMessageContext> {

    public Set<QName> getHeaders() {
        return new TreeSet();
    }

    public boolean handleMessage(SOAPMessageContext context) {
        Boolean outboundProperty = 
            (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outboundProperty.booleanValue()) {
            SOAPMessage message = context.getMessage();
            try {
                SOAPEnvelope envelope = context.getMessage()
                        .getSOAPPart().getEnvelope();
                SOAPFactory factory = SOAPFactory.newInstance();
                String prefix = "X";
                String uri = "http://...wsssecurity...";
                SOAPElement securityElem = 
                        factory.createElement("Security",prefix,uri);
                SOAPElement tokenElem = 
                        factory.createElement("BinarySecurityToken",prefix,uri);
                tokenElem.addTextNode("kjh...897=");
                securityElem.addChildElement(tokenElem);
                SOAPHeader header = envelope.addHeader();
                header.addChildElement(securityElem);

            } catch (Exception e) {
                System.out.println("Exception in handler: " + e);
            }
        } else {
            // inbound
        }
        return true;
    }

    public boolean handleFault(SOAPMessageContext context) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void close(MessageContext context) {
        //
    }
}
A: 

Re John Saunders questions in his comment to my original question:

It seems I require 50 reputation points before I can comment. Also stackoverflow's registration of new IDs is broken (pages says something's broken in web site). So I'm replying using "Your answer".

Does the WSDL describe the headers?

Yes. It also uses SOAP 1.2 bindings that causes some grief. I don't know how good the WSDL is. There is a lot of heavy duty XSD (in separate files).

If so, then doesn't JAX-WS generate the code to add them?

The only tool I've tried that could digest the WSDL was NetBeans 6.5.1 and I asked it to generate classes from the WSDL and to insert the web-service client code for me. That code doesn't add SOAP Headers.