I\'m using Jersey to provide a java REST service to the outside world. I offer some functions that take JSON and I use the Jackson framework in combination with jersey to conver
I had the same problem and solve overriding the ExceptionMapper. Perfect! One extra thing that I needed to do and were not understanding 100% was how to override the JacksonProvider for my application (I don't know if it was related to Jersey's version that I was using - 2.19). Here's my web.xml part that overrides it:
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider
</param-value>
Thanks for your help, an ExceptionMapper for JsonParseException didn't help. I removed the jackson jar files from my projekt and included the jackson sources. Then I modified ord.codehaus.jackson.jaxrs.JsonParseExceptionMapper and JacksonMappingExceptionMapper to return my custom response content. I'm not happy with it, but it works now!
Thanks for your help!
The reason that your custom ExceptionMapper doesn't catch the exceptions is because the Jackson library provides its own exception mappers, which catches the exception before it would be catched by your genereal exception mapper.
Some suggest that you should implement your own exception mappers for JsonParseExceptionMapper and JacksonMappingExceptionMapper, but that, however, will give inconsistent results. See this issue on their GitHub.
To solve this problem, you must make sure that none of the built-in exception mappers are registered. If you're using the jackson-jaxrs-providers library for JSON: jackson-jaxrs-json-provider, make sure that you are only registering either JacksonJaxbJsonProvider.class or JacksonJsonProvider.class in your Application class:
public class MyApplication extends ResourceConfig {
public MyApplication() {
register(JacksonJaxbJsonProvider.class)
}
}
Be aware of the JacksonFeature.class, as it registers the built in ExceptionMappers. Also stay away from the jersey-media-json-jackson library, which automatically will add some built in exception mappers, without you having to do anything at all.
Of course Jackson exception is thrown before: the Jackson provider is called in order to create an object you are expecting in your method. However, with ExceptionMapper you should be able to map not only your exceptions, but also the providers exception.
Are you sure your provider is registered? Does it being called if your throw exception from your method and not from provider?
If the answer to the previous question is "yes", try to implement ExceptionMapper for a concrete exception instead of Throwable.
I ran into a similar issue a while back while using Jackson and Apache CXF. The exception mappers weren't called if the exception didn't happen in my JAX-RS method and instead happened in the JacksonJsonProvider
. The solution in my case was to extend JacksonJsonProvider
, catch the specific Jackson json exceptions, and rethrow them as WebApplicationException.
Here's my overriden readFrom method for my extended JacksonJsonProvider
:
@Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
try {
return super.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream);
} catch (JsonParseException jpe) {
throw new WebApplicationException(jpe, Response.status(Status.BAD_REQUEST)
.entity(new ErrorEntity("Malformed json passed to server: \n" + jpe.getMessage())).build());
} catch (JsonMappingException jme) {
throw new WebApplicationException(jme, Response
.status(Status.BAD_REQUEST)
.entity(new ErrorEntity("Malformed json passed to server, incorrect data type used: \n"
+ jme.getMessage())).build());
}
}