解决LocalDateTime传值JSON格式化问题

本文介绍如何在JDK8中优化使用LocalDateTime,包括自定义转换器和序列化器,以解决JSON解析和序列化问题。通过实现WebMvcConfigurer,注册Converter和自定义序列化、反序列化器,实现对LocalDateTime的高效处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LocalDateTime是JDK8中提供的新功能,极大的优化了原生日期时间类的使用。但是第一次使用该类可能会在传值过程中出现格式化的小问题(如:JSON无法解析前端所传格式,序列化时LocalDateTime成为数组等),以下提供简单的解决方案。

推荐方法:

在WebMvcConfigurer实现类下完成以下两步

1). 注册一个Converter<String, LocalDateTime>实现类,其作用是处理于url所携带的参数上(如:@RequestParam@PathVariable )的LocalDateTime参数;

2). 增加一个序列化、反序列化器,作用为处理实体类的的LocalDateTime属性。

P.S. 经过多轮测试,得出了以上方法,由于该方法需要以上两个步骤,作为完美主义者,我曾尝试用一个步骤解决,但并未如愿以偿,若你有更好的方法,还望不吝赐教,先行谢过。

源码如下:

// import ...

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
	
	/**
	 * 自定义String转LocalDateTime方法,此方法将会作用于url所携带的参数上
	 */
    static class StringToLocalDateTimeConverter implements Converter<String, LocalDateTime> {
        @Override
        public LocalDateTime convert(String s) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            return LocalDateTime.parse(s, formatter);
        }
    }

	/**
	 * 将上述自定义方法进行添加
	 */
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToLocalDateTimeConverter());
    }
	
	/**
	 * 增加序列化与反序列化器,它们将作用于实体类的LocalDateTime属性。
	 */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule module = new JavaTimeModule();
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(pattern));
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(pattern));
        objectMapper.registerModule(module);
        converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
    }
}

其它方法:

url参数:
给参数加上@DateTimeFormat(此注解来自Spring,无需引入其他包),在pattern中标注约定好的格式即可。

public void Test(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime time) {
	...
}

实体类:
在实体类中的属性上添加@JsonFormat(此注解来自Jackson,该包被Spring所依赖,无需导入),同样在pattern中标注好格式。

@Data
public class Demo {

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime time;
    
}

由于这种方法需要对代码中所有的LocalDateTime都进行标注,相对麻烦,且耦合度高,所以不作推荐。

<think>好的,我现在需要帮助用户解决如何在后端使用LocalDateTime类型与数据库的datetime字段进行映射,并设置创建时间的问题。首先,我得回顾一下用户之前的问题和我的回答,确保这次的回答符合之前的上下文。 用户之前问过如何在后端设置创建时间,数据库类型是datetime。我给出了几种方法,包括手动赋、数据库自动生成、ORM框架自动填充以及混合模式。现在用户进一步细化问题,明确后端使用LocalDateTime类型,想知道如何与数据库的datetime字段映射,并设置创建时间。 首先,我需要确认LocalDateTimeJava中与数据库datetime类型的兼容性。根据引用[1],用户提到使用LocalDateTime类型接收数据库的datetime和timestamp字段,这说明LocalDateTime可以正确映射。但需要注意数据库驱动和JDBC版本是否支持,比如MySQL Connector/J 8.0以上才支持LocalDateTime。 接下来,用户需要具体的配置步骤。在之前的回答中,提到了MyBatis-Plus的自动填充功能,这里需要再次强调。用户可能需要知道如何在实体类中使用注解,比如@TableField(fill = FieldFill.INSERT),以及配置元对象处理器来设置LocalDateTime。 另外,引用[3]提到前后端时间处理的问题,特别是日期格式的转换。用户可能在后端接收前端来的时间字符串时需要正确的格式化,比如使用@JsonFormat或@DateTimeFormat注解。但根据用户当前的问题,这部分可能不是重点,但需要提及以确保完整。 现在,我需要整合这些信息,给出具体的步骤: 1. 数据库字段设置:确保数据库的datetime字段有默认CURRENT_TIMESTAMP,这样即使后端不,数据库也会自动填充。但用户可能更希望后端主动设置,所以可能需要结合数据库默认和后端代码。 2. 实体类映射:使用LocalDateTime类型,并添加MyBatis-Plus的自动填充注解。这里需要示例代码,说明如何定义字段和处理器。 3. 类型转换器:如果ORM框架不支持LocalDateTime,可能需要配置类型处理器,比如MyBatis的TypeHandler。 4. 注意事项:时区问题、驱动版本、前后端格式统一。例如,数据库连接字符串中的时区设置,避免前端递带T的格式,需要使用工具类或注解进行格式化。 用户可能遇到的常见问题包括自动填充失效,这可能是因为处理器未正确配置或字段注解错误。另外,数据库驱动不兼容也可能导致映射失败,需要确认版本。 最后,确保回答结构清晰,分步骤说明,并提供代码示例,让用户能够一步步操作。同时,相关问题要引导用户可能遇到的后续问题,比如如何同时设置创建时间和更新时间,或者如何处理不同数据库的差异。</think>### 后端使用`LocalDateTime`与数据库`datetime`字段的映射及创建时间设置方法 #### 一、核心映射配置 **1. 数据库字段定义** 确保数据库表字段定义为`datetime`类型,并设置默认(可选): ```sql CREATE TABLE your_table ( create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' ); ``` **2. Java实体类定义** 使用`LocalDateTime`类型直接映射数据库`datetime`字段: ```java @Data public class YourEntity { @TableField(value = "create_time") // MyBatis-Plus注解 private LocalDateTime createTime; } ``` **3. 驱动兼容性要求** - MySQL需使用**Connector/J 8.0+**驱动(支持JDBC 4.2)[^1] - JDBC连接参数需指定正确时区: ```properties jdbc:mysql://localhost:3306/db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8 ``` #### 二、自动填充创建时间(MyBatis-Plus方案) **1. 实体类注解配置** ```java @Data public class YourEntity { @TableField(fill = FieldFill.INSERT, value = "create_time") private LocalDateTime createTime; } ``` **2. 元对象处理器实现** ```java @Component public class LocalDateTimeMetaHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); } } ``` **3. 自动填充验证** 插入数据时无需手动赋: ```java YourEntity entity = new YourEntity(); mapper.insert(entity); // create_time自动填充当前时间 ``` #### 三、手动赋方案 ```java // 手动设置当前时间(适用于非ORM框架场景) YourEntity entity = new YourEntity(); entity.setCreateTime(LocalDateTime.now()); ``` #### 四、类型转换保障 **1. MyBatis类型处理器** 若框架未自动处理`LocalDateTime`,需在`mybatis-config.xml`添加: ```xml <configuration> <typeHandlers> <typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler"/> </typeHandlers> </configuration> ``` **2. Spring Boot全局配置** 在`application.yml`中指定JDBC类型映射: ```yaml spring: jackson: serialization: WRITE_DATES_AS_TIMESTAMPS: false ``` #### 五、注意事项 1. **时区统一** 数据库、应用服务器、客户端需保持相同时区,建议全部使用`UTC+8`时区 2. **时间格式规范** - 后端接收前端参数时,使用`@DateTimeFormat`定义格式: ```java @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; ``` - 返回给前端时,使用`@JsonFormat`规范输出: ```java @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime createTime; ``` 3. **驱动版本验证** 通过`mvn dependency:tree`检查是否包含: ```xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值