James Baker
James Baker

Reputation: 1256

Deserialization of interfaces using Jackson, where the interface implementation is specified in the serialized object

I have the following sort of structure (simplified to hopefully make the problem clearer):

interface Settings {
    ...
}

interface Component {
    ...
}

class Container {
    Class<? extends Component> component;
    Settings settings;
}

@SettingsClass(MySettings.class)
class MyComponent implements Component{
    ...
}

class MySettings implements Settings{
    ...
}

If I serialize an instance of Container using Jackson, I get a JSON that looks a bit like:

{
    component: "my.package.MyComponent"
    settings: { ... }
}

This is exactly what I want.

But I can't deserialize that JSON because Jackson doesn't know which implementation of Settings to use. At run time, I can retrieve the SettingsClass annotation and identify which class the settings field should be deserialized to.

Is there a way for me to get Jackson to partially deserialize the JSON, and then have it deserialize the rest (i.e. the settings) once I've been able to inspect the component and determine which Settings class to use?

Upvotes: 0

Views: 634

Answers (1)

Michael
Michael

Reputation: 44160

Not really. I had to do something similar recently. I parsed into JsonNode and checked the property manually.

final JsonNode jsonRoot = new ObjectMapper().readTree(jsonString);
//...
Optional.ofNullable(jsonRoot.get("component")).map(JsonNode::textValue) ...

Then serialized the tree into the POJO.

new ObjectMapper().readerFor(theClass).readValue(jsonRoot)

Not amazing, but saves parsing the entire string twice at least.

Upvotes: 1

Related Questions