Jackson将日期字符串反序列化为Long类型时间戳报错如何解决
错误根因
你当前配置的@JsonFormat(shape = JsonFormat.Shape.NUMBER)是告诉Jackson:输入的JSON字段为数字类型的时间戳,可以直接转换为Long类型。但实际输入是ISO8601格式的日期字符串,Jackson尝试直接将字符串强转为Long失败,因此抛出InvalidFormatException。此外你配置的pattern中包含.SSS毫秒位,而示例输入的日期字符串无毫秒值,即使修正shape配置也会出现格式匹配错误。
解决方案
方案1:自定义反序列化器(最通用,适配所有ISO8601 UTC格式日期)
自定义反序列化类处理字符串日期到时间戳毫秒的转换:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; import java.time.Instant; public class IsoDateToLongDeserializer extends StdDeserializer<Long> { public IsoDateToLongDeserializer() { super(Long.class); } @Override public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String dateStr = p.getText().trim(); // Instant.parse原生支持带/不带毫秒的ISO8601 UTC格式日期 return Instant.parse(dateStr).toEpochMilli(); } }
修改字段注解,移除原有错误的@JsonFormat配置,指定自定义反序列化器:
@JsonProperty("timestamp") @JsonPropertyDescription("blah, blah") @JsonDeserialize(using = IsoDateToLongDeserializer.class) public Long timestamp;
方案2:借助JSR310时间类转换(无需自定义反序列化逻辑)
如果你的项目已经引入jackson-datatype-jsr310模块(Spring Boot项目默认内置),可以先将字段定义为Instant类型,Jackson可直接反序列化ISO格式字符串为Instant对象,需要时再获取毫秒值:
@JsonProperty("timestamp") @JsonPropertyDescription("blah, blah") public Instant timestamp; // 业务代码中获取Unix纪元毫秒数 long epochMilli = timestamp.toEpochMilli();
内容的提问来源于stack exchange,提问作者pasaba por aqui
相关产品推荐
相关产品推荐

