9

我在反序列化我正在使用的服务期间使用的类中有以下字段。

private ZonedDateTime transactionDateTime;

我正在使用的服务可能会使用以下模式返回 Date 或 DateTime:yyyy-MM-dd'T'HH:mm:ss.SSSZ

让我举两个服务返回的例子:

  • 2015-11-18T18:05:38.000+0200
  • 2015-11-18T00:00:00.000+0200

虽然第一个效果很好,但后者会在反序列化期间引发以下异常:

java.time.format.DateTimeParseException:无法在索引 23 处解析文本“2015-11-18T00:00:00.000+0200”

我在用着;

  • 春季启动 1.3.1
  • Jackson 2.6.4(包含 JSR310 模块)

这是否需要自定义反序列化类?

4

5 回答 5

5

您可以使用以下注释:

@JsonSerialize(using = MyCustomJsonDateSerializer.class)

或者

@JsonDeserialize(using = MyCustomJsonDateDeserializer.class)

自定义 Jackson 解析日期的方式。那些自定义的 Serializer 和 Deserializer 必须扩展 JsonSerializer 和 JsonDeserializer。例如:

public class MyCustomJsonDateSerializer extends JsonSerializer<Date> {

    @Override
    public void serialize(Date date, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeString(date != null ? ISODateTimeFormat.dateTime().print(new DateTime(date)) : null);
      }
}
于 2016-01-13T11:22:11.157 回答
4

在代码的前面,我使用了带@JsonFormat注释的字段,但删除了它,因为我认为它只是像 JavaDocs 建议的那样用于序列化。

原来我需要添加回那个注释。真正的问题是第 3 方服务响应确实是错误的(它在 XML 中缺少一个包装器元素),导致反序列化失败。错误是:

com.fasterxml.jackson.databind.JsonMappingException:无法从字符串值('2015-11-18T00:00: 00.000+0200'); 没有单字符串构造函数/工厂方法

该字段如下所示:

@JsonFormat(pattern = Constants.DATETIME_FORMAT)
@JacksonXmlProperty(localName = "transactionDate")
private ZonedDateTime transactionDateTime;

我还必须添加@JsonRootName("transaction")到该字段的类中,因为该对象被包装到一个集合中。

于 2016-01-13T15:07:27.690 回答
4

Jackson 反序列化将默认绕过时区信息并使用 ctx 时区覆盖它,所有 ISO8601 都将以 UTC 结束

如果你在春天,这个功能可以被关闭

spring.jackson.deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE=false
于 2018-08-30T08:11:00.520 回答
0

以下配置帮助了我

指定日期时间模式:

public class Timestamp {

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
    private ZonedDateTime timestamp;

}

禁止将 ZonedDateTime 转换为 UTC:

objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);

还有另一个问题,可能很难发现。在我的情况下,我Timestamp使用 RestTemplate 从另一个微服务接收。RestTemplate 可以配置为使用notProjectDefaultObjectMapper,它不受默认 Spring Jackson 配置方法的影响(如应用程序属性,或@Configuration具有Jackson2ObjectMapperBuilderCustomizerbean 定义的类或其他方式)。所以RestTemplate的objectMapper(如果有的话)也应该配置

于 2021-12-17T12:23:53.680 回答
0

我用过

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private ZonedDateTime startDate;

加上jackson-datatype-jsr310图书馆,显然。

Jackson deserialize ISO8601 formatted date-time into Java8 Instant中描述了这个解决方案

于 2020-04-29T16:31:02.797 回答