Reputation: 568
I have to parse a JSON like this in Jackson:
"people": [
{
"personId": 1,
"name": "An",
"friends": [{"personId": 2}]
},
{
"personId": 2,
"name": "Bob",
"friends": [{"personId": 1}]
}
]
This should result in An's friends array containing Bob, and Bob's friends array containing An. I'm using this decorator on the Person class:
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "personId")
The problem is that, during deserialisation, Jackson sets the first person in An's friends to null, as Bob hasn't been parsed yet. What's the best way to work around this?
Upvotes: 0
Views: 110
Reputation: 2550
If you have the possibility to slightly preprocess your JSON, so that the references are pure int
s, the following approach would be the easiest for you:
@Data
@NoArgsConstructor
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "personId")
public class People {
private int personId;
private String name;
private List<People> friends;
}
A little test for the deserialization:
public class ForwardReferenceTest {
@Test
void forwardReference() throws JsonProcessingException {
String json = "{\"people\": [\n" +
" {\n" +
" \"personId\": 1,\n" +
" \"name\": \"An\",\n" +
" \"friends\": [2]\n" +
" },\n" +
" {\n" +
" \"personId\": 2,\n" +
" \"name\": \"Bob\",\n" +
" \"friends\": [1]\n" +
" }\n" +
"]}";
Map<String, List<People>> people = new ObjectMapper().readValue(json, new TypeReference<Map<String, List<People>>>() {
});
assertThat(people.get("people").get(1).getFriends().get(0).getPersonId()).isEqualTo(1);
}
}
Could you give this a try?
Upvotes: 2