Jackson 将日期字符串反序列化为 Long
Posted
技术标签:
【中文标题】Jackson 将日期字符串反序列化为 Long【英文标题】:Jackson deserialize date string to Long 【发布时间】:2022-01-08 02:52:26 【问题描述】:Java Jackson 能否将 json 字符串日期反序列化为 Java Long 字段(从纪元开始的毫秒数)?
这是一个要反序列化的json字段的例子:
"timestamp": "2022-01-02T03:04:05Z",
这是 Java 类中的同一个字段,带有当前注解:
@JsonFormat(shape = JsonFormat.Shape.NUMBER, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC")
@JsonProperty("timestamp")
@JsonPropertyDescription("blah, blah\r\n")
public Long timestamp;
但是,发生了异常:
com.fasterxml.jackson.databind.exc.InvalidFormatException: 不能 从 String 反序列化
java.lang.Long
类型的值 “2022-01-02T06:49:05Z”:不是有效的 Long 值
有什么提示吗?谢谢。
【问题讨论】:
【参考方案1】:Maurice 的答案是正确的,它只是使用了臭名昭著的麻烦和长期过时的 SimpleDateFormat
和 Date
类。没有它们,deserialize
方法也简单得多:
public class LongTimestampDeserializer extends StdDeserializer<Long>
public LongTimestampDeserializer()
this(null);
public LongTimestampDeserializer(Class<?> vc)
super(vc);
/** @throws InvalidFormatException If the timestamp cannot be parsed as an Instant */
@Override
public Long deserialize(JsonParser parser, DeserializationContext ctxt)
throws IOException
String timestamp = parser.getText();
try
return Instant.parse(timestamp).toEpochMilli();
catch (DateTimeParseException dtpe)
throw new InvalidFormatException(
parser, dtpe.getMessage(), timestamp, Long.class);
按照我的理解,反序列化程序应该抛出JsonProcessingException
的一些子类,以防解析错误。 InvalidFormatException
在这种情况下是一个合适的子类。
【讨论】:
【参考方案2】:使用像这样的自定义日期反序列化器:
public class CustomDateDeserializer extends StdDeserializer<Long>
private SimpleDateFormat formatter =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
public CustomDateDeserializer()
this(null);
public CustomDateDeserializer(Class<?> vc)
super(vc);
@Override
public Long deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException, JsonProcessingException
String date = jsonparser.getText();
try
return formatter.parse(date).toInstant().toEpochMilli();
catch (ParseException e)
throw new RuntimeException(e);
接下来用@JsonDeserialize(using = CustomDateDeserializer.class)
注释你的字段。
@JsonDeserialize(using = CustomDateDeserializer.class)
public Long timestamp;
【讨论】:
请不要教年轻人使用早已过时且臭名昭著的麻烦SimpleDateFormat
类。至少不是第一选择。而且不是没有任何保留。我们在java.time
, the modern Java date and time API, 和它的DateTimeFormatter
中做得更好。您已经在使用 java.time(Instant
及其 toEpochMilli
方法)。全力以赴!并避免指定格式化程序以及额外的转换。以上是关于Jackson 将日期字符串反序列化为 Long的主要内容,如果未能解决你的问题,请参考以下文章
Jackson 将 YAML 文件反序列化为 Map(没有自定义反序列化器)