Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access default jackson serialization in a custom serializer

Tags:

java

json

jackson

I want to create a custom serializer which does a tiny bit of work and then leaves the rest for default serialization.

For example:

@JsonSerialize(using = MyClassSerializer.class) public class MyClass {   ... }  public class MyClassSerializer extends JsonSerializer<MyClass> {     @Override     public void serialize(MyClass myClass, JsonGenerator generator,                            SerializerProvider provider)              throws JsonGenerationException, IOException {         if (myClass.getSomeProperty() == someCalculationResult) {             provider.setAttribute("special", true);         }         generator.writeObject(myClass);     }   } 

With the idea of creating other custom serializers for aggregated objects which behave differently based on the 'special' attribute value. However, the above code does not work, as it unsurprisingly goes into an infinite recursion.

Is there a way to tell jackson to use default serialization once I have set the attribute? I don't really want enumerate all the properties like many custom serializers as the class is fairly complex and I don't want to have to do dual maintenance with the serializer every time I change the class.

like image 756
DavidA Avatar asked Jun 25 '15 16:06

DavidA


People also ask

Does Jackson use serializable?

Note that Jackson does not use java. io. Serializable for anything: there is no real value for adding that. It gets ignored.

What is @JsonSerialize?

@JsonSerialize is used to specify custom serializer to marshall the json object.


1 Answers

A BeanSerializerModifier will provide you access to the default serialization.

Inject a default serializer into the custom serializer

public class MyClassSerializer extends JsonSerializer<MyClass> {     private final JsonSerializer<Object> defaultSerializer;      public MyClassSerializer(JsonSerializer<Object> defaultSerializer) {         this.defaultSerializer = checkNotNull(defaultSerializer);     }      @Override     public void serialize(MyClass myclass, JsonGenerator gen, SerializerProvider provider) throws IOException {         if (myclass.getSomeProperty() == true) {             provider.setAttribute("special", true);         }         defaultSerializer.serialize(myclass, gen, provider);     } } 

Create a BeanSerializerModifier for MyClass

public class MyClassSerializerModifier extends BeanSerializerModifier {     @Override     public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {         if (beanDesc.getBeanClass() == MySpecificClass.class) {             return new MyClassSerializer((JsonSerializer<Object>) serializer);         }         return serializer;     } } 

Register the serializer modifier

ObjectMapper om = new ObjectMapper()         .registerModule(new SimpleModule()                 .setSerializerModifier(new MyClassSerializerModifier())); 
like image 100
Sam Berry Avatar answered Sep 20 '22 18:09

Sam Berry