I need to make a custom ExceptionMapper in Jersey to handle the JsonProcessingException returned by Jackson.
The Jackson library already includes ExceptionMapper providers for this exception in the form of JsonMappingExceptionMapper.java and JsonParseExceptionMapper.java (link).
If I add a new provider for this exception mapper in "my.package" I get unpredictable results regarding the selected provider. Sometimes it will select the provider in "my.package" and sometimes it will select the provider in the Jackson library. The code I'm using to scan the packages is below.
PackgesResourceConfig packagesResourceConfig = new PackgesResourceConfig("com.fasterxml.jackson.jaxrs", "my.package");
Proposed Solution
Currently I am getting around this by filtering out the provider in the Jackson library manually. But what I really want to know is whether there is a more acceptable and supported way of doing this.
First I extend PackagesResourceConfig.
public class FilteredPackgesResourceConfig extends PackagesResourceConfig {
private Set<Class<?>> classesToFilter = new HashSet<Class<?>>();
public FilteredPackgesResourceConfig(String... packages) {
super(packages);
}
public FilteredPackgesResourceConfig(Map<String, Object> props) {
super(props);
}
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = super.getClasses();
if (classes != null && classesToFilter != null) {
classes.removeAll(classesToFilter);
}
return classes;
}
public Set<Class<?>> getClassesToFilter() {
return classesToFilter;
}
public void setClassesToFilter(Set<Class<?>> classesToFilter) {
this.classesToFilter = classesToFilter;
}
}
This I use this class to filter out the specific providers I don't want.
FilteredPackgesResourceConfig packagesResourceConfig = new FilteredPackgesResourceConfig("com.fasterxml.jackson.jaxrs", "my.package");
classesToFilter.add(com.fasterxml.jackson.jaxrs.json.JsonMappingExceptionMapper.class);
classesToFilter.add(com.fasterxml.jackson.jaxrs.json.JsonParseExceptionMapper.class);
packagesResourceConfig.setClassesToFilter(classesToFilter);
This solution gives me the desired result of only using the providers I specified. Is there a more correct way of achieving the same result?
I also came across this problem, in my case I solved it by instead of registering com.fasterxml.jackson.jaxrs.json
package I only registered the class I wanted, which in my case was com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
.
There are several ways to do this, I did it using web.xml like so:
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
my.own.package
my.other.package
</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
</param-value>
</init-param>
<init-param>
<param-name>jersey.config.disableMoxyJson</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Note: I'm using Jersey 2.0, in 1.x the property names and servlet class are diferent but the same config is possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With