使用 Jackson 进行自定义时间反序列化

问题描述 投票:0回答:1

我需要处理一组较旧的数据文件,其中除其他信息外,本地数据时间已序列化为表单

“获取时间”:[2024,8,13,9,49,52,662000000]

较新的文件还将包含有关创建数据的时区的信息。

在我的应用程序中,我需要将 Jackson 的本地日期时间反序列化为 ZonedDateTime。该应用程序需要处理任何一种情况,无论有或没有时区信息,以便也使用旧文件。对于较旧的文件,可以假设某个时区,尽管它不包含在文件中,因为我知道数据是在哪里生成的。上面的例子对应的是

2024-08-13T09:49:52.662+01:00

因为 JSON 源自的时区在该日期位于 UTC 偏移量 +01:00。

我如何为此为 Jackson 创建一个自定义解串器?

java datetime jackson deserialization
1个回答
0
投票

我如何为此为 Jackson 创建一个自定义解串器?

这里是帮助你开始的。

class ModelDeserializer extends StdDeserializer<MyModel> {
    ZoneId assumedZoneId = ZoneId.of("Pacific/Norfolk");

    public ModelDeserializer() {
        super(MyModel.class);
    }

    @Override
    public MyModel deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        ArrayNode array = (ArrayNode) node.get("timeOfAcquisition");
        LocalDateTime ldt = LocalDateTime.of(array.get(0).asInt(),
                array.get(1).asInt(), array.get(2).asInt(),
                array.get(3).asInt(), array.get(4).asInt(),
                array.get(5).asInt(), array.get(6).asInt());
        MyModel model = new MyModel();
        model.timeOfAcquisition = ldt.atZone(assumedZoneId);
        return model;
    }
}

基本技巧是从 JSON 中读取数字数组作为

ArrayNode
,并将 7 个元素中的每一个作为
int
传递给
LocalDateTime.of()
。您需要添加数组长度为 7 的验证。并替换 JSON 来源的时区。

我假设了一个这样的模型类:

class MyModel {
    public ZonedDateTime timeOfAcquisition;

    @Override
    public String toString() {
        return "MyModel{timeOfAcquisition=" + timeOfAcquisition + '}';
    }
}

尝试整个事情:

        String json = """
                {
                    "timeOfAcquisition":[2024,8,13,9,49,52,662000000]
                }""";

        ObjectMapper mapper = new ObjectMapper();

        SimpleModule module = new SimpleModule();
        module.addDeserializer(MyModel.class, new ModelDeserializer());
        mapper.registerModule(module);

        MyModel obj = mapper.readValue(json, MyModel.class);
        System.out.println(obj);

此片段的输出是:

MyModel{timeOfAcquisition=2024-08-13T09:49:52.662+11:00[Pacific/Norfolk]}
© www.soinside.com 2019 - 2024. All rights reserved.