Quantcast
Channel: Apache Timeline
Viewing all articles
Browse latest Browse all 5648

CXF How to handle exceptions thrown from providers

$
0
0
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

Viewing all articles
Browse latest Browse all 5648

Trending Articles