Chris DaMour
Chris DaMour

Reputation: 4010

Can you group JSON serialization by property Type

Supposed i have a POJO like this:

class POJO1 {
   TypeA getFirst();
   TypeA getSecond();
   TypeB getThird();
   String getName();
}

I'm looking to create a custom serializer that would output this:

{ "A" : [ serializationOf(first), serializationOf(second) ], "B" : serializationOf(second), "name" : valueOfName() }

But here's the catch, it's not specific to POJO1. Meaning the same serialization takes place for this other POJO:

class POJO2 {
   TypeA getFirst();
   TypeA getSecond();
   TypeB getThird();
   String getName();
}

Or any class that has TypeA or TypeB properties, meaning the methods can change. I prefer not to target a base class or interface as my serializer is to be used by people developing other classes that i've never even imagined. I've been looking at registering TypeA and TypeB serializers, but they don't seem to allow me to change the key of the json object, nor group similar types in any way.

Upvotes: 1

Views: 1137

Answers (2)

Chris DaMour
Chris DaMour

Reputation: 4010

Inspired by the Jackson: How to add custom property to the JSON without modifying the POJO post I found what i was looking for. It is 4 pronged:

  • Add a filter that removes all the types i want to group
  • Make that filter applied for the container types i care about (Object in my case)
  • Add a custom serializer that extends BeanSerializerBase using the technique in the linked answer
  • Add custom group serialization code in that extended BeanSerializerBase using it's _props:BeanWriter[] protected variable

This gives me no extra reflection overhead, and i don't have to know a base type in any code. I don't lose any annotations applied to the bean being serialized as defined by the other dev (since i use Jackson's own PropertyWriters).

I put together a POC over at https://github.com/drdamour/jackson-serializer-fun

Upvotes: 0

Manos Nikolaidis
Manos Nikolaidis

Reputation: 22234

It seems that the JSON document you want to get doesn't have the same structure as the 2 classes, so you can't use binding for POJO1 and POJO2. You can however define a new class with the same structure as the JSON you want to get. E.g.

class BindedPojo {
    TypeA[] A;
    TypeA B;
    String name;

    BindedPojo(TypeA a, TypeA b, String n) {
        A = new TypeA[]{a, b};
        B = b;
        name = n;
    }
}

Then to serialize an object named p1 of type either POJO1 or POJO2:

BindedPojo bp = new BindedPojo(p1.getFirst(), p1.getSecond(), p1.getName());

And just serialize bp to a JSON e.g. with the writeValue method of ObjectMapper. This solution doesn't require POJO1 and POJO2 to have a common base class. It also avoids modifications to the source code of POJO1 and POJO2.

Upvotes: 1

Related Questions