Jeep87c
Jeep87c

Reputation: 1120

How to serialize nested collection of objects with Jackson

Having the following code:

public class ToSerialize {
  List<NestedObject> objs;

  public ToSerialize(List<NestedObject> objs) {
    this.objs = objs;
  }
}

public class NestedObject {
  int intValue = 0;
  String strValue = "Hello world";
}

How, if possible, do I setup Jackson so I get the following CSV as String output:

obj1.intValue,obj1.strValue,obj2.intValue,obj2.strValue,0,"Hello world",0,"Hello world"

I looked into writing my own custom JsonSerializer but can't figure it out. Still, here's my current not working serializer implementation

  @Override
  public void serialize(List<NestedObject> values, JsonGenerator gen, SerializerProvider serializers)
    throws IOException
  {
    int i = 1;
    for (Iterator<VsppAssetEntry> iterator = values.iterator(); iterator.hasNext(); ) {
      VsppAssetEntry entry = iterator.next();
      String fieldName = "obj" + i;
      gen.writeObjectField(fieldName, entry);
      i++;
    }

this is throwing com.fasterxml.jackson.core.JsonGenerationException: Can not write a field name, expecting a value obviously because Jackson wrote a fieldName objs before entering this method.

Upvotes: 3

Views: 3011

Answers (1)

mle
mle

Reputation: 2542

I would suggest Jackson dataformat CSV.

Consider the following CSV Schema:

CsvSchema schema = CsvSchema.builder()
        .addColumn("obj")
        .addColumn("intValue")
        .addColumn("strValue")
        .build()
        .withHeader();

ToSerialize toSerialize = new ToSerialize(Arrays.asList(new NestedObject(), new NestedObject()));

String csv = new CsvMapper()
        .writerFor(ToSerialize.class)
        .with(schema)
        .writeValueAsString(toSerialize);

System.out.println(csv);

and the following custom Serializer…

public class ToSerializeSerializer extends JsonSerializer<ToSerialize> {
    @Override
    public void serialize(ToSerialize toSerialize, JsonGenerator gen, SerializerProvider serializers)
            throws IOException {
        List<NestedObject> objs = toSerialize.getObjs();
        for (int i = 0; i < objs.size(); i++) {
            gen.writeObject("obj" + i);
            gen.writeObject(objs.get(i));
        }
    }
}

…register it on your ToSerialize class…

@JsonSerialize(using = ToSerializeSerializer.class)
public class ToSerialize {
    […]
}

…and it will give you…

obj,intValue,strValue
obj0,0,"Hello world"
obj1,0,"Hello world"

Upvotes: 2

Related Questions