Error handling with CXF interceptors - changing the response message

26,355

Solution 1

And here's the other piece of your puzzle. You're already using JAX-RS, so why not use JAX-WS as well?

This thread and this blog post cover mapping Exceptions into SOAP faults. Short and sweet:

The JAX-WS 2.0 specification demands that the exception annotated with @WebFault must have two constructors and one method [getter to obtain the fault information]:

WrapperException(String message, FaultBean faultInfo)
WrapperException(String message, FaultBean faultInfo, Throwable cause)
FaultBean getFaultInfo()

The WrapperException is replaced by the name of the exception, and FaultBean is replaced by the class name that implements the fault bean. The fault bean is a Java bean that contains the information of the fault and is used by the Web service client to know the cause for the fault.

And there's your mapping. Simply specify implementations of the above signatures in the context of @WebFault and your SOAP API should map these happily. Obviously, the links contain more details.

Solution 2

If you're using JAX-RS, why not setup an exception mapper, and then use that mapper to handle the response.

A simple example:

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class MyExceptionMapper implements
        ExceptionMapper<MyException> {

    @Override
    public Response toResponse(MyException e) {
        return Response.status(Status.NOT_FOUND).build();
    }

}

Then you would need to register the provider in the jaxrs serve by adding:

<jaxrs:providers>
    <bean class="com.blah.blah.blah.blah.MyExceptionMapper"/>  
</jaxrs:providers>

in the server config in the context. With that you have full access to the exception, and can get whatever you want from it.

Share:
26,355
user219882
Author by

user219882

my about me is no longer blank

Updated on April 16, 2020

Comments

  • user219882
    user219882 about 4 years

    I'm trying to handle errors coming from my backend. The handleMessage() is called if an error occurs but the content is an instance of XmlMessage. I would like to change it to my own response - just set the response code and add some message.

    I haven't found any proper documentation which could tell me how to do this...

    These axamples are for REST but I'd like to manage this thing in SOAP too.

    interceptor

    public class ErrorHandlerInterceptor extends AbstractPhaseInterceptor<Message> {
    
        public ErrorHandlerInterceptor() {
            super(Phase.POST_LOGICAL);
        }
    
        @Override
        public void handleMessage(Message message) throws Fault {
            Response response = Response
                .status(Response.Status.BAD_REQUEST)
                .entity("HOW TO GET A MESSAGE FROM AN EXCEPTION IN HERE???")
                .build();
            message.getExchange().put(Response.class, response);
        }
    
    }
    

    context.xml

    <bean id="errorHandlerInterceptor"
        class="cz.cvut.fit.wst.server.interceptor.ErrorHandlerInterceptor" />
    
    <jaxrs:server address="/rest/">
        <jaxrs:serviceBeans>
            <ref bean="restService" />
        </jaxrs:serviceBeans>
        <jaxrs:outFaultInterceptors>
            <ref bean="errorHandlerInterceptor" />
        </jaxrs:outFaultInterceptors>
    </jaxrs:server>
    
  • user219882
    user219882 about 12 years
    And what if I'd like to use SOAP? How can I handle that? Same as for the JAX-RS or do I have to you interceptor?
  • mjwenk
    mjwenk about 12 years
    For soap, I think you have to use an interceptor. I wasn't ever able to figure out exactly what I needed to do to get to work in CXF's soap stuff. Fortunately for me it wasn't much of a problem, but the jax-rs way seems much nicer.
  • user219882
    user219882 about 12 years
    Thank you. I don't accept your answer yet in order to divide the reputation between you two
  • MrGomez
    MrGomez about 12 years
    @Tomas While the effort is noble (I'm glad I helped!), that, unfortunately, isn't how the bounty system works (details). I'm uncomfortable with reconciling this for you because I have a stake in the result, but the option exists to grant an additional bounty if you feel two answers are deserving of it. Sorry for the trouble; I didn't write the system. :)
  • user219882
    user219882 about 12 years
    Oh, that's too bad. I decided to do this: I give the bounty to mjwenk because the reputation helps him more than you and accept your answer since you have links to both REST and SOAP. I guess it is the only fair way (or at least a little bit). Thank you for mentioning it...
  • MrGomez
    MrGomez about 12 years
    @Tomas Entirely reasonable! Thanks for being above board about it and for letting me know. :)
  • Bhuvan
    Bhuvan almost 11 years
    What if I have a following scenario. I have an interceptor that performs validation. And I have an Exception handler as well. If I want to throw my custom exception from the interceptor, will my exception handler's toResponse method be invoked?
  • Bhuvan
    Bhuvan almost 11 years
    You can answer on this question stackoverflow.com/questions/17079790/…
  • Krayo
    Krayo almost 10 years
    If auto-scan has been set (<jaxrs:server address="/rs" basePackages="com.abc.service" />), then no registration required.
  • Marcin Erbel
    Marcin Erbel almost 8 years
    Is there any way to catch exception from interceptor into exception mapper? I can't do it: stackoverflow.com/questions/37984617/…
  • Max
    Max over 7 years
    should be noted: this solution will work anyway but override jackson data parser / databinding at the end