Class A looks like this:
@EqualsAndHashCode(callSuper = true) @Data @AllArgsConstructor public final class A extends TreeSet<B> { private final a; private b; private c; public A(a, b, c) { this.a = a; this.b = b; this.c = c; } }
Class B:
@Data @AllArgsConstructor @EqualsAndHashCode @ToString public final class B { private final int x; private final double y; }
When I serialize a class A object using Jackson:
jsonString = objectMapper.writeValueAsString(class_a_object);
I get a json Array like this:
[ { "x": 3, "y": 3.23 }, { "x": 4, "y": 2.12 },... ]
but the member variables a,b,c are missing. Is there a way I can include them into the json string?
Advertisement
Answer
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 @AllArgsConstructor class A extends TreeSet<B> { private final int a; private final int b; } @Data @AllArgsConstructor @EqualsAndHashCode @ToString class 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 } ] }