Custom SOAP Faults in Apache ServiceMix 4
It can’t be realized without custom processors because although several expression languages can retrieve the exception message, neither the XQuery or XSLT components work with fault messages.
WSDL
<wsdl:definitions targetNamespace="http://www.fernandoribeiro.eti.br/ws/sample" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.fernandoribeiro.eti.br/ws/sample" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xs:schema elementFormDefault="qualified" targetNamespace="http://www.fernandoribeiro.eti.br/ws/sample" xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
<xs:element name="SampleFault"> <!-- great opportunity for a common type -->
<xs:complexType>
<xs:sequence>
<xs:element name="Message" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
...
<wsdl:message name="SampleFault">
<wsdl:part name="SampleFault" element="tns:SampleFault" />
</wsdl:message>
<wsdl:portType name="SamplePortType">
<wsdl:operation name="SampleOperation">
...
<wsdl:fault name="SampleFault" message="tns:SampleFault" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SampleSoapBinding" type="tns:SamplePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
...
<wsdl:operation name="SampleOperation">
<soap:operation ... />
...
<wsdl:fault name="SampleFault">
<soap:fault name="SampleFault" use="literal" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SampleService">
<wsdl:port name="SamplePort" binding="tns:SampleSoapBinding">
<soap:address location="http://ws.fernandoribeiro.eti.br/SampleService/" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
RouteBuilder
package br.eti.fernandoribeiro.ws.sample;
import org.apache.camel.builder.RouteBuilder;
public final class SampleRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
onException(Exception.class).process(new SampleFaultProcessor());
...
}
}
Processor
package br.eti.fernandoribeiro.ws.sample;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public final class SampleFaultProcessor implements Processor {
private static final DocumentBuilderFactory FACTORY = DocumentBuilderFactory.newInstance();
private DocumentBuilder builder;
public SampleFaultProcessor() throws ParserConfigurationException {
builder = FACTORY.newDocumentBuilder();
}
public void process(final Exchange exch) throws ParserConfigurationException {
final Document doc = builder.newDocument();
final Element root = doc.createElementNS("http://www.fernandoribeiro.eti.br/ws/sample", "SampleFault");
final Element msg = doc.createElementNS("http://www.fernandoribeiro.eti.br/ws/sample", "Message");
msg.setTextContent(exch.getException().getMessage());
root.appendChild(msg);
doc.appendChild(root);
exch.getFault().setBody(doc);
}
}
SOAP Response
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring/>
<detail>
<SampleFault xmlns="http://www.fernandoribeiro.eti.br/ws/sample">
<Message>Sample Message</Message>
</SampleFault>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Advertisement