spring-ws
spring-ws copied to clipboard
Support for @WebFault
I have generated classes from WSDL. Fault messages are converted into an Exception
with a faultInfo
(for detail element) and annoted with @WebFault
When I throw the business exception on server side, it's just converted into a generic javax.xml.ws.soap.SOAPFaultException
with just exception message on client side.
Here is my quick&dirty exception resolver:
public class WebFaultAnnotationExceptionResolver implements EndpointExceptionResolver {
private final ConcurrentMap<Class<?>, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class<?>, JAXBContext>();
protected Marshaller createMarshaller(Object target) throws JAXBException {
JAXBContext jaxbContext = jaxbContexts.computeIfAbsent(target.getClass(), clazz -> {
try {
return JAXBContext.newInstance(clazz);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
});
return jaxbContext.createMarshaller();
}
@Override
public boolean resolveException(MessageContext messageContext, Object endpoint, Exception ex) {
Annotation webFault = ex.getClass().getAnnotation(WebFault.class);
if (webFault == null) {
return false;
}
SoapBody soapBody = ((SoapMessage) messageContext.getResponse()).getSoapBody();
SoapFault soapFault = soapBody.addServerOrReceiverFault(ex.getMessage(), null);
try {
Method getFaultInfo = ex.getClass().getMethod("getFaultInfo");
try {
Object detail = getFaultInfo.invoke(ex);
if (detail == null) {
return true;
}
Marshaller marshaller = createMarshaller(detail);
marshaller.marshal(detail, soapFault.addFaultDetail().getResult());
return true;
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (NoSuchMethodException e) {
return true;
}
}
}