How to serialize a class that extends TreeSet with Jackson? How to serialize a class that extends TreeSet with Jackson? json json

How to serialize a class that extends TreeSet with Jackson?


Jackson recognises class A as a collection and register CollectionSerializer to serialise A's instances. We can modify default serialiser and provide custom serialiser. We can use BeanSerializerModifier to do that and reuse collection serialiser in custom implementation. To generate valid JSON you need to provide property name for set values.

Example:

import com.fasterxml.jackson.core.JsonGenerator;import com.fasterxml.jackson.databind.BeanDescription;import com.fasterxml.jackson.databind.JsonSerializer;import com.fasterxml.jackson.databind.SerializationConfig;import com.fasterxml.jackson.databind.SerializationFeature;import com.fasterxml.jackson.databind.SerializerProvider;import com.fasterxml.jackson.databind.json.JsonMapper;import com.fasterxml.jackson.databind.module.SimpleModule;import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;import com.fasterxml.jackson.databind.type.CollectionType;import lombok.AllArgsConstructor;import lombok.Data;import lombok.EqualsAndHashCode;import lombok.ToString;import java.io.File;import java.io.IOException;import java.util.TreeSet;public class ModifyCollectionSerializerApp {    public static void main(String[] args) throws IOException {        A a = new A(1, 2);        a.add(new B(22, 2.2));        a.add(new B(33, 3.3));        SimpleModule aModule = new SimpleModule();        aModule.setSerializerModifier(new ABeanSerializerModifier());        JsonMapper mapper = JsonMapper.builder()                .enable(SerializationFeature.INDENT_OUTPUT)                .addModule(aModule)                .build();        String json = mapper.writeValueAsString(a);        System.out.println(json);    }}class ABeanSerializerModifier extends BeanSerializerModifier {    @Override    public JsonSerializer<?> modifyCollectionSerializer(SerializationConfig config, CollectionType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer) {        return new AJsonSerializer(serializer);    }}class AJsonSerializer extends JsonSerializer<A> {    private final JsonSerializer valuesSerializer;    AJsonSerializer(JsonSerializer valuesSerializer) {        this.valuesSerializer = valuesSerializer;    }    @Override    public void serialize(A value, JsonGenerator gen, SerializerProvider serializers) throws IOException {        gen.writeStartObject();        gen.writeNumberField("a", value.getA());        gen.writeNumberField("b", value.getB());        gen.writeFieldName("values");        valuesSerializer.serialize(value, gen, serializers);        gen.writeEndObject();    }}@EqualsAndHashCode(callSuper = true)@Data@AllArgsConstructorclass A extends TreeSet<B> {    private final int a;    private final int b;}@Data@AllArgsConstructor@EqualsAndHashCode@ToStringclass B implements Comparable<B> {    private final int x;    private final double y;    @Override    public int compareTo(B o) {        return this.x - o.x;    }}

Above code prints:

{  "a" : 1,  "b" : 2,  "values" : [ {    "x" : 22,    "y" : 2.2  }, {    "x" : 33,    "y" : 3.3  } ]}