4

{ "type":"cat", "animal":{"name":"cat"} }

Animal is an abstract class. Cat and Dog are subclass.

Now I am trying to convert json to java object and want to use "type" to get the subclass.

But the type field is out of animal the column.

Thanks in advance :)

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property= "type")
@JsonSubTypes({ @Type(value = Cat.class, name = "cat"),
    @Type(value = Dog.class, name = "dog") })
abstract class Animal {
    public String name;
}



class Cat extends Animal {
public String name;
}

class Dog extends Animal {
public String name;
}

the question is the type is out of animal{}.

if the type is in the animal{} the code will works. but it isn`t ):

0

1 Answer 1

9

It's possible, but type in JSON should looks like "type":"com.test.Cat" (fully qualified name)
Abstract class

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="type")
public abstract class AAnimal 
{
}  

subclasses

public class Cat extends AAnimal
{
   public String name;
} 
public class Dog extends AAnimal
{
   public String name;
}  

now, for json

"{ \"type\":\"com.test.Dog\", \"name\":\"gav-gav\" }"  

it will be Dog instance
and for

"{ \"type\":\"com.test.Cat\", \"name\":\"mew-mew\" }" 

it will be Cat instance
EDIT
In this case use JsonTypeInfo.As.EXTERNAL_PROPERTY. Example

public class Container 
{
   private String type;

   private AAnimal animal;

   public String getType()
   {
      return type;
   }

   public void setType(String type)
   {
      this.type = type;
   }

   public AAnimal getAnimal()
   {
      return animal;
   }

   @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property="type")
   public void setAnimal(AAnimal animal)
   {
      this.animal = animal;
   }
}  

Animal classes

public abstract class AAnimal 
{
   public String name;
}
public class Cat extends AAnimal
{
}
public class Dog extends AAnimal
{
}  

for

"{\"type\":\"com.test.Cat\", \"animal\" : {\"name\":\"cat\" }}"

it works well.
PS. Also you can use use=JsonTypeInfo.Id.MINIMAL_CLASS, in this case you can use only part of fully qualified name
EDIT2

   @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property="type")
   @JsonSubTypes({ @Type(value = Cat.class, name = "cat"), @Type(value = Dog.class, name = "dog") })
   public void setAnimal(AAnimal animal)
   {
      this.animal = animal;
   }  

works well for

"{\"type\":\"cat\", \"animal\" : {\"name\":\"cat\" }}"
Sign up to request clarification or add additional context in comments.

5 Comments

but the type field is not in the animal {}
If the type must be 1 or 2, How can I change the JsonTypeInfo? The type value is given by others and I can not change it to com.package.Cat ): @llya
hi @llya I met a problem again. When I deserialization, I got two type columns:{"type": 1,"type": "1",}
@Felix I don't know answer yet. I may be able to answer in 3 hours. Please, create new question for it
stackoverflow.com/questions/14048738/… because of getting two type field my deserialization failed ):

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.