Get请求-LocalDateTime的转换问题
问题分析
在处理 HTTP GET 请求时,如果尝试接收一个 LocalDateTime 类型的参数,可能会遇到序列化或反序列化的问题。这是因为 URL 参数通常是字符串形式,而 LocalDateTime 是 Java 中的一个日期时间对象,需要适当的格式化才能正确解析。不然可以会出现如下错误:
Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDateTime'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value '2024-08-08 22:22:22'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2024-08-08 22:22:22]
解决方案
一、LocalDateTime 转换器(全局)
get请求的话, 不走反序列化,而是直接将String的值塞给对应的类型,默认是没有转换器,会抛出异常。
配置了转换器后,当用LocalDateTime接收get请求参数的时候,就会进入这个转换器中。
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@Component
public class StringToLocalDateTimeConverter implements Converter<String, LocalDateTime> {private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");@Overridepublic LocalDateTime convert(String source) {return LocalDateTime.parse(source, formatter);}
}
二、显示参数处理
如果不想使用自定义转换器,可以在控制器方法中显式地处理字符串参数,并手动转换为 LocalDateTime:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@RestController
public class MyController {@GetMapping("/test1")public void resolveRequestParamDateTime(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime localDateTime) {log.info("localDateTime:{}", localDateTime);}private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");@GetMapping("/test2")public String getDateTime(@RequestParam("date") String dateString) {LocalDateTime date = LocalDateTime.parse(dateString, formatter);// 处理逻辑return "Received date: " + date;}
}
三、application.yml配置
application.yml配置 SpringBoot2.3.x以及更高的版本,springmvc增加了日期时间格式配置,既可以解决LocalDateTime类型参数解析,也可以解决Date类型参数解析
spring:mvc:date: yyyy-MM-ddtime: HH:mm:ssdate-time: yyyy-MM-dd HH:mm:ss
四、LocalDateTimeConfig
在Spring IOC容器中注入Converter,SpringBoot会自动将IOC容器中的Converter放到GenericConversionService中
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;@Configuration
public class LocalDateTimeConfig {@Beanpublic Converter<String, LocalDateTime> stringToLocalDateTimeConverter() {return new Converter<String, LocalDateTime>() {@Overridepublic LocalDateTime convert(String source) {return LocalDateTime.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));}};}@Beanpublic Converter<String, LocalDate> stringToLocalDateConverter() {return new Converter<String, LocalDate>() {@Overridepublic LocalDate convert(String source) {return LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd"));}};}@Beanpublic Converter<String, LocalTime> stringToLocalTimeConverter() {return new Converter<String, LocalTime>() {@Overridepublic LocalTime convert(String source) {return LocalTime.parse(source, DateTimeFormatter.ofPattern("HH:mm:ss"));}};}
}