I want to create multiple beans for ObjectMapper, mostly differentiating in date format.
I have written the following code -
@Configuration
public class ObjectMapperConfig {
@Primary
@Bean
public ObjectMapper createDefaultObjectMapper() {
return new ObjectMapper();
}
@Bean(name="AOMapper")
public ObjectMapper createFacebookObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZ"));
return objectMapper;
}
@Bean(name="BOMapper")
public ObjectMapper createTwitterObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy"));
return objectMapper;
}
}
While I am able to use AOMapper and BOMapper using @Qualifier annotation, other third party packages which use just ObjectMapper without the Qualifier annotation are unable to get default ObjectMapper.
Is there a way out?
Update: Following is the exception I get
[com.myorg.service.xyz.client.XyzClient]: Factory method 'getUnstarted' threw exception; nested exception is java.lang.RuntimeException: java.io.UncheckedIOException: Cannot construct instance of `java.time.Instant` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2018-03-19T22:56:33.339Z')
at [Source: (ByteArrayInputStream); line: 1, column: 161] (through reference chain: com.myorg.service.xyz.client.WatchResult["updates"]->java.util.ArrayList[0]->com.myorg.service.xyz.client.Announcement["announceTime"]) (code 200)
What I understood from above is that somehow, the XyzClient is not getting the correct default ObjectMapper and therefore unable to deserialize the date format
The problem is that your ObjectMapper
don't know how to deserialize a Instant
class, you need to register the jackson module that provides those custom serializers/deserializers. This module is named jackson-datatype-jsr310
and you can import it (when using maven) with this:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.4</version>
</dependency>
Then, when you create your object mapper you have to register the JavaTimeModule
module.
objectMapper.registerModule(new JavaTimeModule());
So your method should be similar to:
@Bean
@Primary
public ObjectMapper createDefaultObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
return objectMapper;
}