I have a POST service that gets either xml or json in the request paylod and
returns an xml or json response. I use
org.apache.cxf.jaxrs.provider.json.JSONProvider and
org.apache.cxf.jaxrs.provider.JAXBElementProvider for the data binding.

I am looking for a way to handle exceptions thrown from these providers when
an invalid request body is given to the service. I have registered an
ExceptionMapper<Exception> as a provider to the server and it is catch the
exceptions but in some cases I still get a exception stacktrace to my
stdout.

Here is my configuration

Service :

@Path("incident")
public class IncidentService {

    @POST
    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
    public Response createIncident(Incident incident) {
        //...code
        //...more code
    }
}
Exception Mapper:
@Provider
public class ExceptionHandler implements ExceptionMapper<Exception> {

    @Context
    private HttpServletRequest request;

    @Override
    public Response toResponse(Exception exception) {

        String accept = request.getHeader("Accept");
        String mediaType = null;
        if(accept.equals("application/xml")){
            mediaType = "application/xml";
        } else {
            mediaType = "application/json";
        }

        IncidentServiceResponse res = new IncidentServiceResponse();
        res.setErrorMessage(exception.getMessage() + " - " +
exception.getCause().getMessage());

        return Response.status(400).entity(res).type(mediaType).build();
    }
}

Config:

<jaxrs:server address="/">
    <jaxrs:serviceBeans>
        <bean class="com.ba.sysman.services.events.IncidentService"></bean>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <bean
class="org.apache.cxf.jaxrs.provider.json.JSONProvider"></bean>
        <bean
class="org.apache.cxf.jaxrs.provider.JAXBElementProvider"></bean>
        <bean class="com.ba.sysman.providers.ExceptionHandler"></bean>
    </jaxrs:providers>
</jaxrs:server>
Test Cases:

When sending a request with no body in it I get nothing to stdout and the
response below which is what I want.

<response>
    <errorMessage>HTTP 400 Bad Request - Unexpected EOF in prolog at
[row,col {unknown-source}]: [2,0]</errorMessage>
</response>

When I send and invalid request body, lets say Content-Type is set to xml
and I send "abc123" as a body, the response that I get is what I expect
(shown below) but I get a stacktrace to stdout (show below again).

<response>
    <errorMessage>HTTP 400 Bad Request - Unexpected character 'a' (code 97)
in prolog; expected '<' at [row,col {unknown-source}]: [1,1]</errorMessage>
</response>

WARNING: javax.xml.bind.UnmarshalException
 - with linked exception:
[com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character 'a'
(code 97) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]]
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:485)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:417)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:386)
    at
org.apache.cxf.jaxrs.provider.JAXBElementProvider.unmarshalFromInputStream(JAXBElementProvider.java:291)
    at
org.apache.cxf.jaxrs.provider.JAXBElementProvider.doUnmarshal(JAXBElementProvider.java:242)
    at
org.apache.cxf.jaxrs.provider.JAXBElementProvider.readFrom(JAXBElementProvider.java:191)
    at
org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1325)
    at
org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1276)
    at
org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:815)
    at
org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:778)
    at
org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:212)
    at
org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:77)
    at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
    at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:243)
    at
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:223)
    at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:197)
    at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:149)
    at
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
    at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
    at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected
character 'a' (code 97) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at
com.ctc.wstx.sr.StreamScanner.throwUnexpectedChar(StreamScanner.java:647)
    at
com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2054)
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1131)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:164)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:415)
    ... 37 more


What is the proper way to handle these exceptions and how can I prevent get
stack traces to my stdout?

Thanks



--
View this message in context: 
http://cxf.547215.n5.nabble.com/CXF-How-to-handle-exceptions-thrown-from-providers-tp5752908.html
Sent from the cxf-user mailing list archive at Nabble.com.

Reply via email to