在 Spring Boot 中使用 Jackson 的 java.time.* 包是否可以只注册一次 Serializer/Deserializer?
Is there any option to register Serializer/Deserializer only once for java.time.* packages using Jackson in Spring Boot?
您好团队,
我正在开发一个 Spring 引导项目(版本 2.3.4 发布),其中我使用 java.time.LocalDate、java.time.LocalDateTime 和 java.time.LocalTime 数据类型几个 bean 中的属性。
但是,这些字段不会自动反序列化,除非我明确地向它们提供以下注释以及我的自定义反序列化器。
@JsonFormat(pattern="dd-MMM-yyyy")
@JsonDeserialize(using= LocalDateWithStringsDeserializer.class)
private LocalDate date_of_joining;
在这个项目中有400-500多个bean,给所有的bean加上这些注解真的是一件很耗时的工作。
如果没有提供这些注释,我会收到以下错误。
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDate` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('27-May-1999')
我也曾尝试定义一个显式 Bean 以使用我的自定义反序列化器覆盖 Spring Boot objectmapper,但这甚至对我没有帮助。下面提到了相同的代码片段。
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.build();
objectMapper.findAndRegisterModules();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setDateFormat(dateformat);
SimpleModule module = new SimpleModule();
module.addDeserializer(LocalDateTime.class, new MillisOrLocalDateTimeDeserializer());
module.addDeserializer(LocalDate.class, new LocalDateWithStringsDeserializer());
module.addDeserializer(LocalTime.class, new LocalTimeWithStringDeserializer());
objectMapper.registerModule(module);
return objectMapper;
}
我什至在我的项目中的 pom.xml 文件中添加了以下依赖项。
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
请提出解决方案。
所以我想出了解决办法。之前配置的其他一些对象映射器在一个项目中使用 Joda Time,这些对象映射器作为必需的库添加到我的项目的构建路径中。
像我在这个问题中提到的那样,在该项目中修改现有的对象映射器并注册 Java 时间模块和日期和时间的自定义反序列化器解决了这个问题。
您好团队,
我正在开发一个 Spring 引导项目(版本 2.3.4 发布),其中我使用 java.time.LocalDate、java.time.LocalDateTime 和 java.time.LocalTime 数据类型几个 bean 中的属性。
但是,这些字段不会自动反序列化,除非我明确地向它们提供以下注释以及我的自定义反序列化器。
@JsonFormat(pattern="dd-MMM-yyyy")
@JsonDeserialize(using= LocalDateWithStringsDeserializer.class)
private LocalDate date_of_joining;
在这个项目中有400-500多个bean,给所有的bean加上这些注解真的是一件很耗时的工作。
如果没有提供这些注释,我会收到以下错误。
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDate` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('27-May-1999')
我也曾尝试定义一个显式 Bean 以使用我的自定义反序列化器覆盖 Spring Boot objectmapper,但这甚至对我没有帮助。下面提到了相同的代码片段。
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.build();
objectMapper.findAndRegisterModules();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setDateFormat(dateformat);
SimpleModule module = new SimpleModule();
module.addDeserializer(LocalDateTime.class, new MillisOrLocalDateTimeDeserializer());
module.addDeserializer(LocalDate.class, new LocalDateWithStringsDeserializer());
module.addDeserializer(LocalTime.class, new LocalTimeWithStringDeserializer());
objectMapper.registerModule(module);
return objectMapper;
}
我什至在我的项目中的 pom.xml 文件中添加了以下依赖项。
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
请提出解决方案。
所以我想出了解决办法。之前配置的其他一些对象映射器在一个项目中使用 Joda Time,这些对象映射器作为必需的库添加到我的项目的构建路径中。
像我在这个问题中提到的那样,在该项目中修改现有的对象映射器并注册 Java 时间模块和日期和时间的自定义反序列化器解决了这个问题。