Sometimes errors happen during the processing of requests, and you want to return that error as a SOAP Fault message. This recipe will show you how to catch exceptions within your web service routes, and return an appropriate SOAP Fault.
This recipe assumes that you have a project with JAX-WS artifacts created as described in the Generating the service stubs from a WSDL recipe. To use the generated API, you need to include a dependency to that project in your build:
<dependency> <groupId>org.camelcookbook.examples</groupId> <artifactId>ws-payments-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
This recipe's example is based on paymentService.wsdl
, whose transferFunds
operation can return a fault of type FaultMessage
:
<wsdl:portType name="Payment">
<wsdl:operation name="transferFunds">
<wsdl:input message="tns:TransferRequest"/>
<wsdl:output message="tns:TransferResponse"/>
<wsdl:fault name="fault" message="tns:FaultMessage"/>
</wsdl:operation>
</wsdl:portType>
All source files for this recipe are located in the ws-camel-routes
project in the camel-cookbook-web-services
module. The Java code for this recipe is located in the org.camelcookbook.ws.fault
package. The Spring XML files are located under src/main/resources/META-INF/spring
and prefixed with fault
.
In order to return a SOAP Fault from within a Camel route, perform the following steps:
FaultHandler
POJO that has a method to convert an Exception
into a fault type, as defined in our WSDL:import org.camelcookbook.ws.payment_service.FaultMessage; public class FaultHandler { public FaultMessage createFault(Exception exception) { FaultMessage fault = new FaultMessage(exception.getMessage()); fault.setStackTrace(exception.getStackTrace()); return fault; } }
FaultHandler
.In the XML DSL, this is written as:
<route id="wsRoute"> <from uri="cxf:bean:paymentServiceEndpoint"/> <onException> <exception> org.camelcookbook.ws.fault.TransferException </exception> <handled> <constant>true</constant> </handled> <setFaultBody> <method ref="faultHandler" method="createFault"/> </setFaultBody> </onException> <transform> <simple>${in.body[0]}</simple> </transform> <log message="request = ${body}"/> </route>
In the Java DSL, this same route is expressed as:
from(cxfUri) .id("wsRoute") .onException(TransferException.class) .handled(true) .setFaultBody(method(FaultHandler.class, "createFault")) .end() .transform(simple("${in.body[0]}")) .log("response = ${body}");
Camel has the concept of a Fault, or an irrecoverable error, that is expressed as a boolean
fault flag on an exchange. Setting a fault body, as in the example above, implicitly sets this flag. The consuming component, referenced by from
, can determine whether a fault has been raised and process it appropriately as part of its response processing at route completion time. In the case of the Camel CXF Component, if it sees that a fault message has been set on the exchange, it will convert and return that as a SOAP fault.
See Chapter 7, Error Handling and Compensation, for more details on how this recipe's onException
block works.
The FaultHandler
method takes advantage of Camel's parameter binding capabilities. Camel will put the caught exception into an exchange property called CamelExceptionCaught
. Camel's parameter binding will automatically map that property to a method parameter of type exception for any bean or method expression language call-out. Refer to Chapter 3, Routing to Your Code, for more details on Camel's parameter binding capabilities.
18.116.88.157