Search code examples
javaweb-servicessoapjax-ws

Not able to log complete SOAP message in SOAPHandler


I have created a SOAPHandler at client side to log outgoing request to server & added a SOAP header in SOAP message.It is logging the outgoing soap xml without the header part .But at the server end I am able to log the whole message with soap header.

Server side log :

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
    <Credential xmlns="http://soap.header.test.com" password="123" username="ashok"/>
</SOAP-ENV:Header>
<S:Body>
    <ns2:addNumber xmlns:ns2="http://service.ashok.com/">
        <arg0>10</arg0>
        <arg1>200</arg1>
    </ns2:addNumber>
</S:Body>

Client side log

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/> **NO HEADER**
<S:Body>
    <ns2:addNumber xmlns:ns2="http://service.ashok.com/">
        <arg0>10</arg0>
        <arg1>200</arg1>
    </ns2:addNumber>
</S:Body>

My partial SOAPHandler at client side

if (outgoingRequest) {
    SOAPMessage message = context.getMessage();
    SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
    SOAPHeader header = envelope.getHeader();
    if (null == header) {
      header = envelope.addHeader();
    }
    QName credential = new QName("http://soap.header.test.com","Credential");
    SOAPHeaderElement headerElement = header.addHeaderElement(credential);
    QName username = new QName("username");
    headerElement.addAttribute(username, "ashok");
    QName password = new QName("password");
    headerElement.addAttribute(password, "123");

    message.writeTo(System.out);
  }

Please suggest me how to log SOAP message with header part at client side


Solution

  • The problem is you are calling writeTo after the message is modified but you still print the old version (without any header change). I suggest you to use saveChanges method from SOAPMessage

    abstract void saveChanges()

    Updates this SOAPMessage object with all the changes that have been made to it.

    And then try to call the method writeTo. let me know if that works.

    I tried your code as:

    EchoServiceImplService echoService = new EchoServiceImplService();
            HandlerResolver resolver = new HandlerResolver(){
    
                @Override
                public List<Handler> getHandlerChain(PortInfo portInfo){
                    List<Handler> handlers = new ArrayList<Handler>();
                    handlers.add(new LogMessageHandler());
                    return handlers;
                }
            };
            echoService.setHandlerResolver(resolver);
            EchoService port = echoService.getEchoServiceImplPort();
    

    And

    public class LogMessageHandler implements SOAPHandler<SOAPMessageContext> {
    
        @Override
        public boolean handleMessage(SOAPMessageContext context){
            try {
                if ((Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)) {
                    SOAPMessage message = context.getMessage();
                    SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
                    SOAPHeader header = envelope.getHeader();
                    if (null == header)
                        header = envelope.addHeader();
    
                    QName credential = new QName("http://soap.header.test.com", "Credential");
                    SOAPHeaderElement headerElement = header.addHeaderElement(credential);
                    QName username = new QName("username");
                    headerElement.addAttribute(username, "ashok");
                    QName password = new QName("password");
                    headerElement.addAttribute(password, "123");
    
                    message.writeTo(System.out);
                    return true;
                }
    
            } catch (Exception e) {
                System.err.println("An error in handler occurs.");
            }
            return false;
        }
    

    And I'm able to see the full SOAPMesssage at client side, just call the handler before send the request to the server.

    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
       <Credential xmlns="http://soap.header.test.com" password="123" username="ashok"/></S:Header>
    <S:Body>
       <ns2:echo xmlns:ns2="http://echo.soap.ws.jax.koitoer.com/">
           <arg0>Koitoer echo </arg0>
       </ns2:echo>
    </S:Body>
    </S:Envelope>