1

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.

Chris DaMour
  • 3,650
  • 28
  • 37

2 Answers2

1

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.

Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
  • yeah this is what i have, but i have to use a whole mess of reflection to construct the BindedPojo...basically I'm compiling unknown types into a known type. But this causes too reflection loops (mine & jacksons) which i wasn't too happy with – Chris DaMour Sep 03 '15 at 20:59
  • If reflection is the problem I would recommend defining an interface with the getters and have each POJO implement that. This [answer](http://stackoverflow.com/a/31030804/1413133) may be useful in that case. – Manos Nikolaidis Sep 03 '15 at 21:35
  • i can't assume an interface. A dev tomorrow might add TypeA getZ() – Chris DaMour Sep 03 '15 at 23:57
  • also i lose any annotations on POJO1 or POJO2 using this method. – Chris DaMour Sep 04 '15 at 23:52
0

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

Community
  • 1
  • 1
Chris DaMour
  • 3,650
  • 28
  • 37