0

I save the payload of events as JSON string into a database. To only have one version of the events in code while still being able to read old events I want to "upcast" the serialized data before deserialization.

I thought about something like this:

public Object deserialize(String data, Class<?> clazz) throws IOException {
    data = upcaster.upcast(data, clazz);
    return objectMapper.readValue(data, clazz);
}

But this means I transform the string into some JSON object twice. Once for upcasting the data and once inside the standard jackson mapper.

Is there a way to customize jackson between building the json-object and building my event object?

Something like:

@override
updateData(clazz, jsonData) {
    if(clazz.equals(SpecificEvent.class)) {
        if(!jsonData.containsKey("addedInfo")) {
            jsonData.put("addedInfo", "foo");
        }
    }
}

Alternatively, I could add my own deserializer that changes the given JSON data before calling the standard deserializer I guess?

What's the normal way of doing something like this with jackson?

letsintegreat
  • 3,328
  • 4
  • 18
  • 39
andymel
  • 4,538
  • 2
  • 23
  • 35

1 Answers1

0

One option is custom deserialization with a dedicated deserializer class (per your own class). You would then have to maintain the deserializer class to make sure that it provides any missing data.

It should work for a handful of classes, if you have a lot then there might be better ways.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • Yes I could do the whole deserialization (string to object) but I would prefer to just alter the JSON on the fly and just use the standard (not custom) deserialization. Any idea how to do that? – andymel Oct 24 '19 at 07:21
  • @andymel ah, I thought you wanted to avoid that. Besides, you asked for the normal way, and that is the normal way. Jackson doesn't seem to offer any json-to-json functionality, which is understandable. You'd have to get a JSON transformer library like [JOLT](https://github.com/bazaarvoice/jolt) or [jsonpatch](http://jsonpatch.com). – Kayaman Oct 24 '19 at 07:26
  • yes, this would be the approach form my first code box in the question, but then I would build a json object from the string, alter it, build the string again and give this to jackson which again would build a json object out of my string. Can I get the default deserializer in my custom deserializer and just call it there? – andymel Oct 24 '19 at 09:08
  • @andymel No you wouldn't. You would deserialize the String, and at the same time introduce any missing values. Standard approach, nothing is done twice. It's described in paragraph 3 of the link I gave. – Kayaman Oct 24 '19 at 09:10
  • True, but then I would have to do the object initialization myself. That's why I am asking if I can get the default deserializer inside my custom deserializer (haven't found that part). In pseudocode something like customDeserializer[standardDeserializer(string -> string+newStuff)] – andymel Oct 25 '19 at 14:29
  • 1
    @andymel ah, now I understand. Then these should help you https://stackoverflow.com/questions/6834677/jackson-mapper-post-construct and https://stackoverflow.com/questions/18313323/how-do-i-call-the-default-deserializer-from-a-custom-deserializer-in-jackson/18405958#18405958 – Kayaman Oct 25 '19 at 14:57
  • Thanks a lot! I will have a look at https://stackoverflow.com/a/18405958/7869582. This is referenced in one of your links and looks promising. – andymel Oct 28 '19 at 16:30