问题描述
public class MyClass {
private LocalDate myDate;
}
我必须将值存储为 yyyy-MM-dd 而不是 [yyyy,M,d]
这可以通过创建一个 LocalDateSerializer 来完成,如 https://stackoverflow.com/a/38731094/10850340 (DateTimeFormatter.ISO_LOCAL_DATE) 中所示
在我的场景中,接收数据的来源有多个。其中之一将日期发送为 ISO_INSTANT '2011-12-03T10:15:30Z'。 LocalDateDeserializer:
public class LocalDateDeserializer extends StdDeserializer<LocalDate> {
private static final long serialVersionUID = 1L;
protected LocalDateDeserializer() {
super(LocalDate.class);
}
@Override
public LocalDate deserialize(JsonParser jp,DeserializationContext ctxt)
throws IOException,JsonProcessingException {
return LocalDate.parse(jp.readValueAs(String.class));
}
}
抛出以下警告:
已解决 [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Text '2021-02-25T00:52:00.000Z' Could not be parsed,unparsed text found at index 10;嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:无法解析文本 '2021-02-25T00:52:00.000Z',在索引 10 处找到未解析的文本(通过引用链:MyClass["myDate"])]
我的理解是接收到的字符串不能解析为 LocalDate
: LocalDate.parse(jp.readValueAs(String.class));
让 LocalDateDeserializer 接受任何有效日期格式但返回 LocalDate
提前致谢!
解决方法
如果您只需要将日期从 Date
对象转换为 LocalDate
,则在填充 MyClass
实例时:
Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
java.util.Date
代表时间线上的一个瞬间,而不是“日期”。
但是在 Java 9 中,您可以执行以下操作:
LocalDate date = LocalDate.ofInstant(input.toInstant(),ZoneId.systemDefault());
不是在反序列化器中进行转换,您可以在将值设置为 MyClass
实例之前在映射器方法本身中处理它,因为您有多个具有多种日期时间格式的源正在使用。否则,您将不得不处理 de 序列化程序中的条件,以处理您将要接收日期的不同格式。如果您在实际将数据设置到实体的映射器方法中处理它(考虑到您有一个 DTO 类),您可以为来自不同来源的不同日期格式提供特定实现。
如果您仍想使用解串器,请对不同的日期格式使用 DateTimeFormatter
并进行相应设置:
@Override
public LocalDate deserialize(JsonParser jp,DeserializationContext ctxt)
throws IOException,JsonProcessingException {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MMM-dd");
if (**somecondition**) {
dtf = DateTimeFormatter.ofPattern("yyyy-MMM-dd");
}
LocalDate dt = dtf.parseLocalDate(yourinput);
return dt;
}
,
格式的可选部分
您可以在格式模式字符串中使用可选部分。这用方括号括起来,表示在解析过程中可能存在或不存在的日期时间字符串的一部分。像这样:
private static final DateTimeFormatter inputFormatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd['T'HH:mm:ssX]");
如果您确定附加不相关的时间和偏移量(Z
是 UTC 偏移量)没有改变日期,您现在可以这样解析:
for (String inputString
: new String[] { "2011-12-03T10:15:30Z","2013-11-21" }) {
LocalDate date = LocalDate.parse(inputString,inputFormatter);
System.out.format("%-20s parsed to %s%n",inputString,date);
}
输出:
2011-12-03T10:15:30Z parsed to 2011-12-03
2013-11-21 parsed to 2013-11-21
,
对于我的特定场景,我知道只有两种格式可以输入日期。我可以检查它是哪种格式并进行相应处理。
我发布了在我的场景中有效的方法,但我确信还有更多“稳健”的解决方案。
booktabs = TRUE