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 ):

Felix
  • 1,253
  • 7
  • 22
  • 41

1 Answers1

8

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\" }}"
Ilya
  • 29,135
  • 19
  • 110
  • 158
  • but the type field is not in the animal {} – Felix Dec 26 '12 at 09:08
  • 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 – Felix Dec 26 '12 at 10:00
  • hi @llya I met a problem again. When I deserialization, I got two type columns:{"type": 1,"type": "1",} – Felix Dec 27 '12 at 04:01
  • @Felix I don't know answer yet. I may be able to answer in 3 hours. Please, create new question for it – Ilya Dec 27 '12 at 07:16
  • http://stackoverflow.com/questions/14048738/serialization-and-deserialization-with-jackson-exception because of getting two type field my deserialization failed ): – Felix Dec 27 '12 at 07:32