Search code examples
web-servicessoapspring-ws

Customize endpoint mapping in spring-ws


I'm implementing a SOAP web service using Spring WS.

Most of my implementation is done using types with @Endpoint annotations and methods in these types with @SoapAction annotations. Some endpoint interceptors also help glue things together.

I'm using Spring exception handling with SoapFaultAnnotationExceptionResolver that enriches the SoapFault with some specific details.

This works very well. But I have a customer requirement that says that I also have to provide customized SoapFaults for those cases where the service is invoked with an invalid soap-action. Meaning, a soap action for which I have no matching @SoapAction annotation.

What happens now is that Spring logs this:

[WARN] org.springframework.ws.server.EndpointNotFound No endpoint mapping found for [AxiomSoapMessage {http://www.example.com/myservice/xml.schema/2010/06/01}MyRequest]

I get this returned along with a 404 return code from the Jetty server that hosts this web service.

How can I catch these exceptions and add some custom soapfault handling in this situation? It seems like if only org.springframework.ws.NoEndpointFoundException had a @SoapFault annotation, I could have it go through my exception resolver and customize it that way. But it doesn't, unfortunately.

I think I may have to implement some custom "catch-all" endpoint mapping but I'm just not sure how to do this, and how to ensure that mapping to the specific endpoints are attempted first.

Anyone have a suggestion for how to do this?


Solution

  • The exception seems to be thrown from the class MessageDispatcher in the method dispatch:

    mappedEndpoint = getEndpoint(messageContext);
    if (mappedEndpoint == null || mappedEndpoint.getEndpoint() == null) {
        throw new NoEndpointFoundException(messageContext.getRequest());
    

    I suggest to extends this class and instead of throwing an exception, you could add a soap fault as such:

    SoapMessage response = (SoapMessage) messageContext.getResponse();
    String faultString = "any message"
    SoapBody body = response.getSoapBody();
    SoapFault fault = body.addServerOrReceiverFault(faultString, getLocale());
    

    You can take a look SimpleSoapExceptionResolver that deals with exceptions on the endpoints.