Customizing ObjectMapper in a JAX-RS application
If you use Jackson as the JSON provider in your JAX-RS application, you may want to redefine the default Jackson behaviour or even fine-tune the serializarion and deserialization processes.
It can be achieved with a
ContextResolver
for
ObjectMapper
:
@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperContextResolver() {
this.mapper = createObjectMapper();
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
private ObjectMapper createObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
return mapper;
}
}
Under the hood, the
ObjectMapper
instance created above will be picked by the
JacksonJsonProvider
class, the Jackson implementation for
MessageBodyReader
and
MessageBodyWriter
that binds JSON content to and from Java objects in JAX-RS.
If, for some reason, you need to access the
ObjectMapper
directly, use the
@Context
annotation to inject
Providers
in your JAX-RS resource or provider classes:
@Context
private Providers providers;
Then look up the
ContextResolver
to get the
ObjectMapper
instance:
ContextResolver<ObjectMapper> resolver =
providers.getContextResolver(ObjectMapper.class, MediaType.WILDCARD_TYPE);
ObjectMapper mapper = resolver.getContext(ObjectMapper.class);
I usually use the following serialization and deserialization settings:
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
For applications with Java 8 or above, I also register the following modules:
mapper.registerModule(new Jdk8Module());
mapper.registerModule(new JavaTimeModule());
mapper.registerModule(new ParameterNamesModule());
Don’t forget to add the following dependencies to your project:
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>