How to serialize a List content to a flat JSON object with Jackson?

Viewed 10539

Given the following POJOs ..

public class City {

    private String title;
    private List<Person> people;
}

...

public class Person {

    private String name;
    private int age;
}

I would like to let Jackson serialize instances of the classes to the following example JSON:

{
    "title" : "New York",
    "personName_1" : "Jane Doe",
    "personAge_1" : 42,
    "personName_2" : "John Doe",
    "personAge_2" : 23 
}

The JSON format is defined by an external API which I cannot change.

I already found that I can annotate the list field with a custom serializer such as:

@JsonSerialize(using = PeopleSerializer.class)
private List<Person> people;

... and here is a basic implementation I tried:

public class PeopleSerializer extends JsonSerializer<List<Person>> {

    private static final int START_INDEX = 1;

    @Override
    public void serialize(List<Person> people, 
                          JsonGenerator generator, 
                          SerializerProvider provider) throws IOException {
        for (int i = 0; i < people.size(); ++i) {
            Person person = people.get(i);
            int index = i + START_INDEX;
            serialize(person, index, generator);
        }
    }

    private void serialize(Person person, int index, JsonGenerator generator) throws IOException {
        generator.writeStringField(getIndexedFieldName("personName", index), 
                                   person.getName());
        generator.writeNumberField(getIndexedFieldName("personAge", index), 
                                   person.getAge());
    }

    private String getIndexedFieldName(String fieldName, int index) {
        return fieldName + "_" + index;
    }

}

However, this fails with an:

JsonGenerationException: Can not write a field name, expecting a value

I also looked into using Jackson's Converter interface but that's not suitable for unwrapping the nested list objects.

I am also aware of @JsonUnwrapped but it is not designed to be used with lists.

Related posts

Related posts (deserialization)

Related library

2 Answers
Related