Hello all, some questions about intercepting and transforming an object pre-serialization.
Some background:
Lately, I have been using the Spring-Data-Rest project, which leverages Jackson for (de)serialization. I have found myself in a situation where I wish to
selectively transform a single field in an object prior to serialization and I have lost myself in the weeds searching for an elegant solution. I'd like to clear up my befuddlement about the question in the subject line, describe my situation, what I have attempted so far as well as try to find an elegant solution for what I'm trying to do.
Spring-data-rest uses a "Resource" object that contains the target object in a "content" field annotated with the @JsonUnwrap annotation so that the object's fields are placed directly in the output instead of in a "content" object. This makes sense and works perfectly for many use cases. The output to HTTP requests is the result of the serialization of this object.
The first thing that I tried was to register a BeanSerializerModifier. I did this because I wanted to transform only a single field in the domain object and to leverage default serialization for the rest of the object. This worked perfectly in unit testing but during integration testing, the object appeared as a sub-object of "content" in the final output. So close, yet so far.
After some research, I found a few Stack Overflow posts describing similar situations. The root cause was that using a custom serializer (or apparently, a BeanSerializerModifier) causes Jackson to ignore the @JsonUnwrap annotation. This is actually in the documentation for the annotation, but I have not yet been able to find out the motivation for disabling functionality like this. I accept that the above method that I tried to use is a non-starter, but I would appreciate a larger picture view of why this is the case.
Currently, I'm trying to implement an "UnwrappingBeanSerializer", however this has come complete with its own problems. Irritatingly, the "serialize" method on the object is final, which means that I cannot intercept the serialize call with my subclass. The most I can do is override the serializeFields method. By then it is too late; the object serialization has begun and apparently I am responsible for serializing every field of a fairly complex object. I cannot seem to figure out how to take advantage of default serialization at this point. For some reason, calling super.serializeFields results in exceptions.
As a last resort, I'm willing to serialize all fields manually. However, I would prefer to work out a better, more elegant solution. Am I barking up the wrong tree here or is there a better solution?
Thank you very much for any help anyone can offer. I am so very close on this but have been stymied at every turn!