近期在做项目的时候,对于时间类型的参数,前端不同的人在写代码的时候传参格式各不一样(可能是不同的日历控件默认的格式不一样),每换一个人就要强调一遍格式,后面想了想,还是我自己在后端兼容处理一下算了
问题:每换一个格式可能就会出现类似下面的异常报错:
Cannot deserialize value of type `java.time.LocalDateTime` from String "2024-09-20T16:40:50.233S"
翻了一下笔记,发现既然在返回数据给前端的时候可以自定义序列化器(springboot返回json数据时double或者bigdeimal保留两位小数的通用处理方法(个人记笔记)_springboot bigdecimal 保留2位小数-CSDN博客),那么应该也能自定义反序列化器才对,于是就带着试一试的心理写了一下,问题还真解决了,废话不多说,直接上代码:
自定义时间反序列化器:
public class DefaultLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLocalDateTimeDeserializer.class);
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
String input = p.getText();
return parse(input);
}
/**
* 日期型字符串转化为日期 格式
*/
public static LocalDateTime parse(String input) {
if (StringUtils.isBlank(input)) {
return LocalDateTime.now();
}
for (String parsePattern : CommonConstants.parsePatterns) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(parsePattern);
LocalDateTime localDateTime = LocalDateTime.parse(input, formatter);
return localDateTime;
} catch (Exception e) {
LOGGER.error("日期解析失败,解析格式:{},解析值:{}", parsePattern, input);
}
}
return LocalDateTime.now();
}
}
在对应的字段上指定反序列化器:
@NotNull
@Schema(description="发布日期")
@JsonDeserialize(using = DefaultLocalDateTimeDeserializer.class)
private LocalDateTime publishDate = LocalDateTime.now();
支持的时间格式:不支持的,只要在这个数组里面加就行了
//时间转换格式
String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"};
PS:如果参数类型是用的java.util.Date类型,也可以这么做,只是在定义DefaultLocalDateTimeDeserializer 的时候泛型参数改为Date就行