简体   繁体   中英

How to add interceptors to a wsdl2java (CXF) generated client?

I am trying to add some logging to the inbound / outbound traffic of a wsdl2java generated client. I have the client generated and using it as follows:

Pseudo code:

MyService ws = new MyService().getMyServiceSoap12();
((BindingProvider)ws).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, webServiceAddress); // for dynamic endpoints...

Is there any way I can add some interceptors? I am using it in a Spring application by the way!

You can implement your own javax.xml.ws.handler.soap.SOAPHandler if you need customized logging or handling SOAP messages in a different way, here is how:

MyService ws = new MyService().getMyServiceSoap12();

BindingProvider wsBindingProvider = (BindingProvider) ws;

// Get a copy of the handler chain for a protocol binding instance
List<Handler> handlers =
    wsBindingProvider.getBinding().getHandlerChain();

// Add your handler(s)
handlers.add(new MySoapMessageLogger());

// We need to setHandlerChain because setHandlerChain
// returns a copy of List<Handler>
wsBindingProvider.getBinding().setHandlerChain(handlers);

The MySoapMessageLogger may look like this:

public class MySoapMessageLogger implements SOAPHandler<SOAPMessageContext> {

    private static final Logger logger = 
        LoggerFactory.getLogger(MySoapMessageLogger.class);

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean isRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        // Retrieve the message contents
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        context.getMessage().writeTo(stream);
        
        // You've got your XML message and can log it right away or
        // beautify it with some library before sending to log
        logger.trace((isRequest ? "Request:" : "Response:") + stream.toString());

        return true;
    }

    /* For the logging purposes the following methods can be leaved as stubs */

    @Override
    public Set<QName> getHeaders() {
        return null;
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return false;
    }

    @Override
    public void close(MessageContext context) {
    }
}

I am not sure if your question is asking how to enable the built-in request/response logging, or rather replace and/or enhance existing logging facilities.

Assuming the former, I suggest looking at Debugging and Logging and Configuration sections of the CXF User Guide . The most important point is that CXF uses Java SE logging by default which means you'll need to toss a SLF4J bridge in your project if you want to use something else.

To enable logging merge these bits (note cxf namespace) in your Spring configuration:

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:cxf="http://cxf.apache.org/core"
      xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <cxf:bus>
        <cxf:features>
            <cxf:logging/>
        </cxf:features>
    </cxf:bus> 
</beans> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM