💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
- 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老
- 导航
- 檀越剑指大厂系列:全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
- 常用开发工具系列:罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
- 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
- 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
- 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
博客目录
- 一.BUG 描述
- 1.现象
- 2.原因
- 二.解决方案
- 1.添加依赖
- 2.添加注解
- 三.全局配置
- 1.@JsonComponent
- 2.自定义
- 3.@Configuration
一.BUG 描述
1.现象
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type
java.util.Date
from String “2023-11-30 22:31:23”: not a valid representation (error: Failed to parse Date value ‘2023-11-30 22:31:23’: Cannot parse date “2023-11-30 22:31:23”: while it seems to fit format ‘yyyy-MM-dd’T’HH:mm:ss.SSSX’, parsing fails (leniency? null))
at [Source: (StringReader); line: 1, column: 634] (through reference chain: com.kwan.springbootkwan.entity.csdn.BusinessInfoResponse[“data”]->com.kwan.springbootkwan.entity.csdn.BusinessInfoResponse A r t i c l e D a t a [ " l i s t " ] − > j a v a . u t i l . A r r a y L i s t [ 0 ] − > c o m . k w a n . s p r i n g b o o t k w a n . e n t i t y . c s d n . B u s i n e s s I n f o R e s p o n s e ArticleData["list"]->java.util.ArrayList[0]->com.kwan.springbootkwan.entity.csdn.BusinessInfoResponse ArticleData["list"]−>java.util.ArrayList[0]−>com.kwan.springbootkwan.entity.csdn.BusinessInfoResponseArticleData$Article[“postTime”])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
2.原因
实体类是 Date 类型,但是 json 字符串是 yyyy-MM-dd’T’HH:mm:ss.SSSX 的时间字段,时间格式不匹配导致,json 字符串转实体类失败了。
二.解决方案
1.添加依赖
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.8.8</version>
</dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.8.8</version>
</dependency><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-mapper-asl</artifactId><version>1.9.13</version>
</dependency>
2.添加注解
添加@JsonFormat 注解,指定时间格式为 yyyy-MM-dd HH:mm:ss 就不会报错了,
@TableField(value = "postTime")
@ApiModelProperty(value = "时间")
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date postTime;
三.全局配置
1.@JsonComponent
@JsonFormat 注解并不能完全做到全局时间格式化,使用 @JsonComponent 注解自定义一个全局格式化类,分别对 Date 和 LocalDate 类型做格式化处理。
@JsonComponent
public class DateFormatConfig {@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")private String pattern;@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilder() {return builder -> {TimeZone tz = TimeZone.getTimeZone("UTC");DateFormat df = new SimpleDateFormat(pattern);df.setTimeZone(tz);builder.failOnEmptyBeans(false).failOnUnknownProperties(false).featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).dateFormat(df);};}@Beanpublic LocalDateTimeSerializer localDateTimeDeserializer() {return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));}@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());}
}
2.自定义
但还有个问题,实际开发中如果我有个字段不想用全局格式化设置的时间样式,那该怎么处理呢?
@Data
public class OrderDTO {@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")private LocalDateTime createTime;@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")private Date updateTime;
}
@JsonFormat
注解的优先级比较高,会以@JsonFormat
注解的时间格式为主。
3.@Configuration
注意:在使用此种配置后,字段手动配置
@JsonFormat
注解将不再生效。
@Configuration
public class DateFormatConfig2 {@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")private String pattern;public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");@Bean@Primarypublic ObjectMapper serializingObjectMapper() {ObjectMapper objectMapper = new ObjectMapper();JavaTimeModule javaTimeModule = new JavaTimeModule();javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());objectMapper.registerModule(javaTimeModule);return objectMapper;}@Componentpublic class DateSerializer extends JsonSerializer<Date> {@Overridepublic void serialize(Date date, JsonGenerator gen, SerializerProvider provider) throws IOException {String formattedDate = dateFormat.format(date);gen.writeString(formattedDate);}}@Componentpublic class DateDeserializer extends JsonDeserializer<Date> {@Overridepublic Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {try {return dateFormat.parse(jsonParser.getValueAsString());} catch (ParseException e) {throw new RuntimeException("Could not parse date", e);}}}public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {@Overridepublic void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {gen.writeString(value.format(DateTimeFormatter.ofPattern(pattern)));}}public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {@Overridepublic LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException {return LocalDateTime.parse(p.getValueAsString(), DateTimeFormatter.ofPattern(pattern));}}
}
觉得有用的话点个赞
👍🏻
呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙