为 ObjectMapper 创建多个 bean
creating multiple beans for ObjectMapper
我想为 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 而没有 Qualifier 注释的第三方包无法获得默认的 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,因此无法反序列化日期格式
能不能重写第三方库的bean,设置合适的ObjectMapper。它是在第三方库中到处使用还是在一个可重复使用的地方使用?如果到处都使用它,那么覆盖每个 bean 可能是不可行的。如果他们在一个地方使用它,您可能可以创建自己的 @Primary bean 来覆盖他们的默认值。
此外,从外观上看,您似乎是以给定格式向这些第 3 方库发送日期。你能不能标准化你给这些图书馆日期的格式?
问题是你的 ObjectMapper
不知道如何反序列化一个 Instant
class,你需要注册提供这些自定义的 jackson 模块 serializers/deserializers .这个模块被命名为 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;
}
我想为 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 而没有 Qualifier 注释的第三方包无法获得默认的 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,因此无法反序列化日期格式
能不能重写第三方库的bean,设置合适的ObjectMapper。它是在第三方库中到处使用还是在一个可重复使用的地方使用?如果到处都使用它,那么覆盖每个 bean 可能是不可行的。如果他们在一个地方使用它,您可能可以创建自己的 @Primary bean 来覆盖他们的默认值。
此外,从外观上看,您似乎是以给定格式向这些第 3 方库发送日期。你能不能标准化你给这些图书馆日期的格式?
问题是你的 ObjectMapper
不知道如何反序列化一个 Instant
class,你需要注册提供这些自定义的 jackson 模块 serializers/deserializers .这个模块被命名为 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;
}