当前位置: 首页 > 知识库问答 >
问题:

Jackson-无法反序列化带有时区偏移量的datetime“在索引23处找到的未分析文本”

段干祺
2023-03-14

我的日期时间必须来自前端,具有时区偏移量:2017-07-04t06:000.000+01:00

我不能把它和杰克逊反序列化。错误是:

    @NotNull
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS aZ")
    private LocalDateTime time;

共有1个答案

祁星阑
2023-03-14

模式a用于解析AM/PM,它不在输入字符串中,这就是为什么会出现解析错误。

输入格式匹配offsetdatetime,可以用相应的内置格式化程序datetimeformatter.iso_offset_date_time解析该格式,因此可以在反序列化器对象中使用该格式化程序并将其注册到模块中。还必须从字段中删除JSONFormat注释。

ObjectMapper om = new ObjectMapper();
JavaTimeModule module = new JavaTimeModule();
LocalDateTimeDeserializer deserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
module.addDeserializer(LocalDateTime.class, deserializer);
om.registerModule(module);

这将解析输入并将其转换为LocalDateTime。在我所做的测试中,LocalDateTime的值被设置为2017-07-04t06:00

om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

它将LocalDateTime输出为2017-07-04t06:00,也可以使用自定义格式化程序:

LocalDateTimeSerializer serializer = new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS a"));
module.addSerializer(LocalDateTime.class, serializer);

上面的序列化程序将输出字段为2017-07-04t06:000.000am。请注意,z模式不能工作,因为LocalDateTime没有时区信息,并且无法解析其偏移量--因为当反序列化为LocalDateTime时,输入(+01:00)中的偏移量信息丢失了。

另一种选择(无需配置对象映射器)是在注释中使用正确的模式

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS[xxx]")
private LocalDateTime time;

请注意,我使用了模式[xxx],因为偏移量(+01:00)可以是可选的:反序列化时,由于LocalDateTime没有关于时区和偏移量的信息,因此该信息将丢失,因此在序列化时将找不到该字段--使该字段可选(使用[]分隔符)使其同时适用于反序列化和序列化。

这将反序列化输入2017-07-04t06:00.000+01:00并序列化为2017-07-04t06:00.000(注意,序列化中不使用可选偏移量,因为LocalDateTime没有此类信息)。

如果需要不同的反序列化和序列化格式,还可以创建自定义类并在字段中对它们进行Anotation:

public class CustomDeserializer extends LocalDateTimeDeserializer {
    public CustomDeserializer() {
        super(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    }
}

public class CustomSerializer extends LocalDateTimeSerializer {
    public CustomSerializer() {
        super(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS a"));
    }
}

// in this case, don't use @JsonFormat
@JsonSerialize(using = CustomSerializer.class)
@JsonDeserialize(using = CustomDeserializer.class)
private LocalDateTime time;

这将使用格式2017-07-04T06:00.000+01:00进行反序列化,并使用格式2017-07-04T06:00.000进行序列化。

 类似资料: