Reputation: 195
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 <{}xxx>,<{}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
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
// 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
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