为ObjectMapper创建多个bean

时间:2018-03-26 12:49:01

标签: spring-boot java-8 jackson fasterxml

我想为ObjectMapper创建多个bean,主要区分日期格式。

我写了以下代码 -

@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;
    }
}

虽然我可以使用@Qualifier注释使用AOMapper和BOMapper,但是其他仅使用ObjectMapper而没有使用限定符注释的第三方包无法获取默认的ObjectMapper。

有出路吗?

更新:以下是我得到的例外

[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)

我从上面了解到,不知何故,XyzClient没有获得正确的默认ObjectMapper,因此无法反序列化日期格式

2 个答案:

答案 0 :(得分:2)

问题是你的ObjectMapper不知道如何反序列化Instant类,你需要注册提供那些自定义序列化器/反序列化器的jackson模块。此模块名为jackson-datatype-jsr310,您可以将其导入(使用maven时):

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9.4</version>
</dependency>

然后,当您创建对象映射器时,您必须注册JavaTimeModule模块。

objectMapper.registerModule(new JavaTimeModule());

所以你的方法应该类似于:

@Bean
@Primary
public ObjectMapper createDefaultObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());
    return objectMapper;
}

答案 1 :(得分:0)

您可以覆盖第三方库的bean并设置相应的ObjectMapper。它是在第三方图书馆或一个可重复使用的地方使用的吗?如果在整个地方使用它,那么覆盖每个bean可能是不可行的。如果他们在一个地方使用它,你可能可以创建自己的@Primary bean来覆盖它们的默认值。

另外,从外观上看,您似乎以给定格式向这些第三方库发送日期。你能否将这些图书馆的格式标准化为日期?