How would I create a custom deserializer for Jackson for this?
Here’s to get you started.
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;
}
}
The basic trick is to read the array of numbers from the JSON as an ArrayNode
and pass each of the 7 elements as int
to LocalDateTime.of()
. You will want to add validation that the array has length 7. And substitute the time zone where your JSON comes from. Also I am leaving to you to extend the code to handle the case where time zone is included in the JSON.
I have assumed a model class like this:
class MyModel {
public ZonedDateTime timeOfAcquisition;
@Override
public String toString() {
return "MyModel{timeOfAcquisition=" + timeOfAcquisition + '}';
}
}
To try the whole thing out:
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);
Output from this snippet is:
MyModel{timeOfAcquisition=2024-08-13T09:49:52.662+11:00[Pacific/Norfolk]}