Reputation: 3539
Can Java Jackson deserialize a json string date into a Java Long field (milliseconds from epoch)?
This is an example of json field to be deserialized:
"timestamp": "2022-01-02T03:04:05Z",
and this is the same field in the Java class, with the current annotations:
@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;
However, an exception happens:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type
java.lang.Long
from String "2022-01-02T06:49:05Z": not a valid Long value
Any hint? Thanks.
Upvotes: 1
Views: 2794
Reputation: 86379
The answer by Maurice is correct, it only suffers from using the notoriously troublesome and long outdated SimpleDateFormat
and Date
classes. Also the deserialize
method is much simpler without them:
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);
}
}
}
The way I understand it the deserializer should throw some subclass of JsonProcessingException
in case of a parsing error. InvalidFormatException
is a suitable subclass in this case.
Upvotes: 3
Reputation: 7401
Use a custom date deserializer like this one:
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);
}
}
}
Next annotate your field with @JsonDeserialize(using = CustomDateDeserializer.class)
.
@JsonDeserialize(using = CustomDateDeserializer.class)
public Long timestamp;
Upvotes: 2