【SpringBoot系列】SpringBoot时间字段格式化

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

  • 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
    • 常用开发工具系列:罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

一.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.添加依赖

xml 复制代码
<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 就不会报错了,

apl 复制代码
@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 类型做格式化处理。

java 复制代码
@JsonComponent
public class DateFormatConfig {

    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;

    @Bean
    public 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);
        };
    }

    @Bean
    public LocalDateTimeSerializer localDateTimeDeserializer() {
 return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
 return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
    }
}

2.自定义

但还有个问题,实际开发中如果我有个字段不想用全局格式化设置的时间样式,那该怎么处理呢?

java 复制代码
@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 注解将不再生效。

java 复制代码
@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
    @Primary
    public 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;
    }

    @Component
    public class DateSerializer extends JsonSerializer<Date> {
        @Override
        public void serialize(Date date, JsonGenerator gen, SerializerProvider provider) throws IOException {
 String formattedDate = dateFormat.format(date);
            gen.writeString(formattedDate);
        }
    }

    @Component
    public class DateDeserializer extends JsonDeserializer<Date> {

        @Override
        public 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> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeString(value.format(DateTimeFormatter.ofPattern(pattern)));
        }
    }

    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException {
 return LocalDateTime.parse(p.getValueAsString(), DateTimeFormatter.ofPattern(pattern));
        }
    }
}

觉得有用的话点个赞 👍🏻 呗。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

相关推荐
舒一笑1 天前
PandaCoder 2.4.3 震撼发布!
后端·程序员·intellij idea
dwedwswd2 天前
亲子娱乐升级!Docker 电视盒子 ADB 安装助手,儿童 APP 一键装满电视
docker·娱乐·电视盒子
猫头虎8 天前
解决升级IDEA2025.2后,每次打开Maven项目爆红的问题:Windows和Mac解决方案
java·ide·macos·maven·intellij-idea·idea·intellij idea
舒一笑9 天前
PandaCoder:致敬MyBatis Log Plugin,但我们做得更极致!
后端·程序员·intellij idea
那我掉的头发算什么9 天前
【数据结构】反射、枚举、lambda表达式以及补充知识
java·jvm·数据结构·intellij idea
fatiaozhang952710 天前
晶晨S905L3SB芯片_安卓9.0_高安版_支持外置WIFI_线刷固件包
android·华为·电视盒子·刷机固件·机顶盒刷机
我命由我1234512 天前
PDFBox - PDFBox 加载 PDF 异常清单(数据为 null、数据为空、数据异常、文件为 null、文件不存在、文件异常)
java·服务器·后端·java-ee·pdf·intellij-idea·intellij idea
舒一笑13 天前
🚀 PandaCoder 2.0.0 - ES DSL Monitor & SQL Monitor 震撼发布!
后端·ai编程·intellij idea
我命由我1234513 天前
Spring Boot - Spring Boot 静态资源延迟响应(使用拦截器、使用过滤器、使用 ResourceResolver)
java·spring boot·后端·spring·java-ee·intellij-idea·intellij idea
叶落阁主15 天前
IdeaVim 新插件推荐- Vim CmdFloat 优化搜索/命令执行框
pycharm·vim·intellij idea