I'm currently facing a problem with error codes and messages using Spring WS.
We are using Spring WS 2.0 with a JAXB2 binding and the @Endpoint and @PayloadRoot annotations for convenience.
Our endpoint looks like this:
@Endpoint
public class MyEndpoint() {
private static final String MY_NAMESPACE=...;
@PayloadRoot(namespace=MY_NAMESPACE, localPart="myPart")
public MyPartResponse handleMyPart(MyPart myPart) {
....
}
}
We use soap only as a thin wrapper around a POX message, defined by the XSD. This also means we use return codes and messages instead of faults.
Each response inherits from
<xs:complexType name="ResultBase">
<xs:sequence>
<xs:element name="errorCode" type="tns:ErrorCode" />
<xs:element name="errorMessage" type="xs:string" />
</xs:sequence>
</xs:complexType>
and adds some specifics in case of success, like this:
<xs:element name="MySpecificResponse">
<xs:complexType>
<xs:complexContent>
<xs:extension base="tns:ResultBase">
<xs:sequence>
<xs:element name="mySpecificElement" type="tns:MySpecificType" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
All the exceptions being thrown inside the handleMyPart method can be cleanly mapped.
However two types of errors remain uncaught and generate faults instead of a clear error message:
At the end of the day, these are issues that are relevant to every POX webservice using Spring WS. How should one intercept these exceptions and map then onto a response object?
Remember though: all response objects are slightly different as they all inherit from the common one, but add some unique optional content to it.
Spring MVC provides exception handling for your web application to make sure you are sending your own exception page instead of the server-generated exception to the user. The @ExceptionHandler annotation is used to detect certain runtime exceptions and send responses according to the exception.
You have to provide implementation to use your error handler, map the response to response entity and throw the exception. Create new error exception class with ResponseEntity field. Custom error handler which maps the error response back to ResponseEntity.
The @ExceptionHandler is an annotation used to handle the specific exceptions and sending the custom responses to the client. Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown.
The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation's reason field. Although we can only return a generic error message, we can specify exception-specific error messages.
One approach that's worked well for me is this:
For XSD validation errors, extend the AbstractValidatingInterceptor to provide custom handling of XSD validation errors, and set it as the validatingInterceptor bean in the Spring context.
For malformed XML, extend MessageDispatcherServlet. Override doService to catch DomPoxMessageException, and add your own custom handling when you catch that exception. Set your customized MessageDispatcherServlet as the spring-ws servlet in the web.xml.
I've written this up with details ad nauseum in my blog post here:
http://www.dev-garden.org/2011/09/03/handling-pox-errors-in-spring-ws-part-1/
-Larry
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With