I have JSON structured like:
{
"id" : "123",
"name" : [ {
"stuff" : [ {
"id" : "234",
"name" : "Bob"
}, {
"id" : "345",
"name" : "Sally"
} ]
} ]
}
That I want to map to the following data structure:
MyInterface1
@Value.Immutable
@JsonSerialize(as = ImmutableMyInterface1.class)
@JsonDeserialize(as = ImmutableMyInterface1.class)
public interface MyInterface1 {
String id();
@JsonDeserialize(using = MyInterface1Deserializer.class)
List<MyInterface2> name();
}
MyInterface2
@Value.Immutable
@JsonSerialize(as = ImmutableMyInterface2.class)
@JsonDeserialize(as = ImmutableMyInterface2.class)
public interface MyInterface2 {
@JsonDeserialize(using = StuffDeserializer.class)
Map<String, MyInterface3> stuff();
}
MyInterface3
@Value.Immutable
@JsonSerialize(as = ImmutableMyInterface3.class)
@JsonDeserialize(as = ImmutableMyInterface3.class)
public interface MyInterface3 {
String id();
String name();
}
I'm using an ObjectMapper with readValue(stringWithJson,MyInterface1.class) to map this JSON to MyInterface1, which should continue down the chain to MyInterface3. This setup was working when I was using a List in MyInterface2, i.e. List<MyInterface3> name();
However, I want this to be a map instead of a list, ideally with "id" from the inner JSON as the key. This would allow me to get values with the following syntax:
MyInterface1.get(0).MyInterface2.get("id1").name();
The problem is that when attempting to create a custom StuffDeserializer.class, I'm getting the error:
Can not deserialize instance of com.foo.ImmutableMyInterface2$Json out of START_ARRAY token
when trying to do:
public Map<String, MyInterface3> deserialize(JsonParser jsonParser, DeserializationContext ctxt)
throws IOException {
MyInterface2 foo = Unmarshaller.OBJECT_MAPPER.readValue(jsonParser, MyInterface2.class); // error here
...
I think this is because Jackson is expecting "stuff" to be a List 'cause of the JSON array. What's the best way to deserialize this JSON to a map that uses values from the inner JSON as a key?