课程名称:Java工程师2022版
课程章节:SSM开发社交网站
课程内容:
①疑难杂症:关于解决因DateTime类型被转为LocalTimeDate而出现的序列化的问题
课程收获:
关于数据库中获取Date类型的问题
控制台报错:
控制台:08:23:07 DEBUG [http-nio-8080-exec-1] o.s.w.s.DispatcherServlet - Failed to complete request: org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class java.time.LocalDateTime]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.fu.reader.utils.ResponseUtils["data"]->java.util.LinkedHashMap["evaluations"]->java.util.ArrayList[0]->java.util.LinkedHashMap["create_time"])
而根据提示进行依赖的添加:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.1</version>
</dependency>
然而却是将年月日时分秒数据分开打印了下来,在前端处理仍然很麻烦
解决方案:
自定义一个LocalTimeDate对象的Json转换器,保证与java.util.Date输出相同的结果即可
1. 自定义LocalTimeDate序列化类
public class CustomLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
public void serialize(LocalDateTime dateTime, JsonGenerator generator, SerializerProvider sp) throws IOException, JsonProcessingException {
long time = dateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
generator.writeNumber(time);
}
}
2. 自定义ObjectMapper类
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
this.registerModule(new JavaTimeModule());
}
public class JavaTimeModule extends SimpleModule {
public JavaTimeModule() {
super(PackageVersion.VERSION);
this.addSerializer(LocalDateTime.class, new CustomLocalDateTimeSerializer());
}
}
}
3. 在Spring配置文件中注册ObjectMapper Bean
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fu.reader.config.CustomObjectMapper"/>
</property>
</bean>
输出结果如下:
造成该现象的原因:
在MyBaits 3.4.5版本之前数据库Datetime类型(如create_time)的字段数据会被转换为java.util.Date
在MyBatis 3.4.5版本后,会被转化为java.time.LocalDateTime
如果引入了高版本的MyBatis,或者MyBatis-Plus,在Jackson对LocalDateTime对象序列化支持的不好,就会产生上面的异常与处理结果。
(通过右键菜单快速查找依赖的依赖版本)
如图,MyBatis版本为3.5.10