1 package de.spring.webservices.client;
3 import java.io.IOException;
4 import java.util.Iterator;
6 import javax.xml.transform.Source;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10 import org.springframework.oxm.Unmarshaller;
11 import org.springframework.oxm.XmlMappingException;
12 import org.springframework.ws.WebServiceMessage;
13 import org.springframework.ws.client.core.FaultMessageResolver;
14 import org.springframework.ws.soap.SoapBody;
15 import org.springframework.ws.soap.SoapFault;
16 import org.springframework.ws.soap.SoapFaultDetail;
17 import org.springframework.ws.soap.SoapFaultDetailElement;
18 import org.springframework.ws.soap.SoapMessage;
19 import org.springframework.ws.soap.client.core.SoapFaultMessageResolver;
21 // maven-jaxb2-plugin for WSDL DOES generate again the objects in web-services-spring-jaxb2-globalxsds :(
22 // So I guess it is better to use the objects generated in this package
23 // than the ones from globalxsds even if they should be the same.
24 import de.spring.webservices.client.auto.GeneralFault;
27 * Enables us to log custom Fault remote messages.
30 public class CustomFaultMessageResolver implements FaultMessageResolver {
32 private static final Logger LOGGER = LoggerFactory.getLogger(CustomFaultMessageResolver.class);
34 private final FaultMessageResolver defaultMessageResolver = new SoapFaultMessageResolver();
36 private Unmarshaller unmarshaller;
39 public void resolveFault(WebServiceMessage message) throws IOException {
41 // Same behavior as default message resolver (SoapFaultMessageResolver) but this implementation also
42 // logs error information.
43 if (LOGGER.isErrorEnabled()) {
45 logErrorInformation(message);
46 } catch (Exception ex) {
47 LOGGER.error("CustomFaultMessageResolver exception:", ex);
51 defaultMessageResolver.resolveFault(message);
54 private void logErrorInformation(WebServiceMessage message) throws XmlMappingException, IOException {
55 SoapMessage soapMessage = (SoapMessage) message;
56 SoapBody body = soapMessage.getSoapBody();
57 SoapFault soapFault = body != null ? body.getFault() : null;
58 SoapFaultDetail detail = soapFault != null ? soapFault.getFaultDetail() : null;
61 Iterator<SoapFaultDetailElement> iterator = detail.getDetailEntries();
62 while (iterator.hasNext()) {
63 SoapFaultDetailElement bodyElement = iterator.next();
64 Source detailSource = bodyElement.getSource();
65 // TODO: How to check if I am receiving GeneralFault before trying to unmarshal?
66 // Right now there will be exception if unmarshal doesn't return a GeneralFault object.
67 GeneralFault error = (GeneralFault)this.unmarshaller.unmarshal(detailSource);
68 LOGGER.error("TECHNICALERROR:");
69 LOGGER.error(error.getTechnicalError());
70 LOGGER.error("ELEMENTS:");
71 error.getElements().forEach(element -> {
72 LOGGER.error("MESSAGE: " + element.getMessage());
73 LOGGER.error("MESSAGEARGS:");
74 element.getMessageArgs().forEach(messageArg -> LOGGER.error(messageArg));
80 public void setUnmarshaller(Unmarshaller unmarshaller) {
81 this.unmarshaller = unmarshaller;