Hejk
Hejk

Reputation: 195

Apache CXF : get XML request causing Fault

I have a webservice which expects a certain request format. When I send a non valid request format, I have the following error :

<faultcode>soap:Client</faultcode>
<faultstring>Unmarshalling Error: unexpected element (uri:"", local:"aaaa"). Expected elements are &lt;{}xxx>,&lt;{}yyy></faultstring>

When this occurs I need to send an e-mail. In this e-mail I need the incoming request (the XML I sent to the webservice).

I tried by implementing a CXF interceptor:

public class ExceptionInterceptor extends AbstractSoapInterceptor {

    /**
     * Logger
     */
    private final static Logger LOGGER = LoggerFactory.getLogger(ExceptionInterceptor.class);

    /**
     * Constructeur
     */
    public ExceptionInterceptor() {
        super(Phase.PRE_LOGICAL);
    }

    public void handleMessage(SoapMessage message) throws Fault {
        Fault fault = (Fault) message.getContent(Exception.class);
        Throwable ex = fault.getCause();

        if (ex instanceof UnmarshalException) {
            LOGGER.error("Error in incoming message", ex);

            // TODO : send email
        }
    }
}

but... how can I get the original message I sent to the webservice here? Apache CXF interceptors are not much documented. :(

Thanks in advance !

Hejk

Upvotes: 1

Views: 1579

Answers (1)

pedrofb
pedrofb

Reputation: 39241

You can log the soap messages using the default CXF loggers LoggingInInterceptor and LoggingOutInterceptor or use a custom interceptor to extract the payload

Using CXF loggers

// output log using log4j
//LogUtils.setLoggerClass(org.apache.cxf.common.logging.Log4jLogger.class);
yourService = new YourService(wsdlURL, SERVICE_NAME);
port = yourService.getServicePort(); 

Client client = ClientProxy.getClient(port);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());

The messages will be written through console. You can use log4j or configure java.util.logging. See more examples here

Custom interceptor

public class MyInterceptor extends AbstractPhaseInterceptor<Message> {
    public MyInterceptor () {
        super(Phase.RECEIVE);
    }

    public void handleMessage(Message message) {
        //Get the message body into payload[] and set a new non-consumed  inputStream into Message
        InputStream in = message.getContent(InputStream.class);
        byte payload[] = IOUtils.readBytesFromStream(in); 
        //log payload...
        ByteArrayInputStream bin = new ByteArrayInputStream(payload);
        message.setContent(InputStream.class, bin);
    }

    public void handleFault(Message messageParam) {
        //Invoked when interceptor fails
    }
}

Adding the interceptor programmatically

 WebClient.getConfig(client).getOutInterceptors().add(new MyInterceptor());

Upvotes: 1

Related Questions