问题背景
最近在Spring Boot项目中遇到了一个常见的日期时间处理问题:当使用LocalDateTime接收前端传来的"2025-12-04 15:10:42"格式参数时,系统直接返回400错误。然而,如果前端传递"2025-12-04T15:10:42"格式,一切正常。
java
// 前端传递的JSON数据:
{
"analyzeTime": "2025-12-04 15:10:42"
}
// 后端接收的实体类:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime analyzeTime;
// 错误信息:
{
"code": 400,
"message": "Http消息不可读异常:您未按照接口要求传递参数"
}
问题分析
LocalDateTime默认使用ISO-8601格式:"yyyy-MM-dd'T'HH:mm:ss"- 习惯使用:
"yyyy-MM-dd HH:mm:ss"(中间是空格而非'T') Spring Boot默认使用Jackson进行JSON序列化和反序列化。Jackson针对Java 8时间类型有专门的模块jackson-datatype-jsr310,但默认使用ISO格式。- 错误发生在请求参数绑定阶段,甚至不会进入Controller方法。这是因为Spring框架在处理请求体时,首先会尝试将JSON字符串反序列化为Java对象,如果格式不匹配,直接抛出异常。
解决方法
在yaml中进行如下配置
yaml
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
加上全局配置Jackson完美解决问题:
java
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @version 1.0.0
* @auther Knight DLS zhangtao
* @date 2025年12月4日16:29:12
*/
@Configuration
public class LocalDateTimeConfiguration {
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
//返回时间数据序列化
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
//接收时间数据反序列化
builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
};
}
}
PS:我在使用@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解后,前端传递"2025-12-04 15:10:42"格式仍然报错。跟着网上说的配置Jackson的Java 8时间模块支持也不行。
java
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
后面说什么配置Jackson的JavaTimeModule
java
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// 注册JavaTimeModule才能让@JsonFormat生效
mapper.registerModule(new JavaTimeModule());
// ❌ 以下配置会覆盖@JsonFormat注解
// mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
return mapper;
}
}
我当时直接就配了我上面说的全局配置Jackson,就没有来尝试配置JavaTimeModule了。感兴趣的可以自己试一试。