Ihor Patsian
Ihor Patsian

Reputation: 1298

Deserialization of dynamic attribute of JSON entity using Jackson

There is JSON entity that has value dynamic attribute:

   {
    "name" : "name1",
    "value" : {"different structures: strings, enums, arrays, custom entities"}
   }

Java representation of the entity:

public class Entity {
    public String name;
    public Object value;
}

In value can be passed completely different JSON structures. Every time value should be mapped to different POJOs.

Is there any common approach to deserialize value attribute to particular entities except additional deserializing of the value attribute content (Map<String, String> structure)?

Upvotes: 2

Views: 2372

Answers (3)

Ihor Patsian
Ihor Patsian

Reputation: 1298

In order to know the exact type to what I should deserialize value new attribute valueType should be added. Additionally, custom deserializer should be implemented to handle deserialization to the desired type.

Entity class is extended with valueType and @JsonDeserialize annotation:

public class Entity {
    public String name;
    @JsonDeserialize(using = EntityValueDeserializer.class)
    public Object value;
    public Class valueType;
}

JSON is changed correspondingly:

   {
    "name" : "name1",
    "value" : "some string" | 10 | "any custom entity",
    "valueType" : "java.lang.String" | "java.lang.Integer" | "any custom type"
   }

Then implement custom deserializer EntityValueDeserializer that gets valueType and proceed deserialization of value to valueType:

public class EntityValueDeserializer extends JsonDeserializer<Object>
{

   public Object deserialize(JsonParser jp, DeserializationContext ctx) throws IOException
   {
      ObjectCodec codec = jp.getCodec();
      JsonNode node = codec.readTree(jp);
      Entity entity = ((Entity) jp.getParsingContext().getCurrentValue());
      return codec.treeToValue(node, entity.valueType);
   }

}

Upvotes: 0

Michael Gantman
Michael Gantman

Reputation: 7808

You can ALWAYS deserialize any valid JSON document into class Map<String, Object> you don't have to do "additional" deserialization. Just change your public Object value; into public Map<String, Object> value; and it should work.

Upvotes: 1

nevets1219
nevets1219

Reputation: 7706

I've used either @JsonSubTypes (serialize into different types) or @JsonDeserialize (custom serialization) to do this. You can see some examples at https://www.baeldung.com/jackson-annotations

Upvotes: 1

Related Questions