我需要处理一组较旧的数据文件,其中除其他信息外,本地数据时间已序列化为表单
“获取时间”:[2024,8,13,9,49,52,662000000]
较新的文件还将包含有关创建数据的时区的信息。
在我的应用程序中,我需要将 Jackson 的本地日期时间反序列化为 ZonedDateTime。该应用程序需要处理任何一种情况,无论有或没有时区信息,以便也使用旧文件。对于较旧的文件,可以假设某个时区,尽管它不包含在文件中,因为我知道数据是在哪里生成的。上面的例子对应的是
2024-08-13T09:49:52.662+01:00
因为 JSON 源自的时区在该日期位于 UTC 偏移量 +01:00。
我如何为此为 Jackson 创建一个自定义解串器?
我如何为此为 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]}