0

I need to deserialize some JSON to Java class. I have the following JSON:

{
  "list": [[{
        "type": "text",
        "subType": "ss"
     },
     {
        "type": "image",
        "subType": "text"
     }
]]
}

and I have the following Java classes:

public abstract class BaseClass {
    public String type;
    public String subType;
}

public class Text extends BaseClass {
   ...
}

public class Image extends BaseClass {
}

and I need deserialize in this way, if type equals image and subType equals text I need to deserialize into Text class otherwise I need deserialize to Image class.

How can I do it?

John
  • 1,375
  • 4
  • 17
  • 40
  • 2
    Does this answer your question? [Custom JSON Deserialization with Jackson](https://stackoverflow.com/questions/19158345/custom-json-deserialization-with-jackson) – Héctor Nov 20 '19 at 08:02
  • @Héctor Thanks, but this approach not working for me. – John Nov 20 '19 at 08:18

2 Answers2

1

You don't need a custom deserializer. Mark your BaseClass with the following annotations, and deserialize with an ObjectMapper:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true)
@JsonSubTypes({@JsonSubTypes.Type(value = Text.class, name = "text"), @JsonSubTypes.Type(value = Image.class, name = "image")
})
public abstract class BaseClass {
    public String type;
    public String subType;
}

JsonTypeInfo defines to use value of type field for type name. JsonSubTypes associates type names with java classes

Vitaly Roslov
  • 313
  • 1
  • 8
  • Yes, but I need to do something like this: I have one abstract class, for instance, ```BaseClass``` and three subclasses which extends ```BaseClass```, ```MyClass1```, ```MyClass2``` and ```MyClass3```. I need to deserialize my JSON to ```MyClass1``` if type equals text and subtype equals image and instantiates ```MyClass 2``` if type equals text and subtype equal text and instantiate ```MyClass3``` if type equals image and not does it matter what is subtype equals. – John Nov 21 '19 at 08:12
  • So you want to use two properties to select a Subtype. As far as I know it has not been implemented in Jackson. You should implement a custom deserializer, like the other answer describes. – Vitaly Roslov Nov 21 '19 at 09:55
0

You can implement your own deserializer like so:

public class BaseClassDeserializer extends StdDeserializer<BaseClass> { 

    public BaseClassDeserializer(Class<?> vc) { 
        super(vc); 
    }

    @Override
    public BaseClass deserialize(JsonParser jp, DeserializationContext ctxt) 
      throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        String type = node.get("type").asText();
        String subType = node.get("subType").asText();

        if("image".equals(type) && "text".equals(subType)){
            /* create Text class
            return new Text */
        } else {
            /* create Image class
            return new Image(args...) */
        }
    }
}
w1sh
  • 68
  • 9