私は@JsonTypeInfo
ジャクソンに@class
具体的なタイプ情報を探すようにプロパティを調べるように指示するために使用しています。ただし、@class
特にコンテキストからサブタイプを推測できる場合は、指定する必要がない場合があります。 それを行うための最良の方法は何ですか?
JSONの例を次に示します。
{
"owner": {"name":"Dave"},
"residents":[
{"@class":"jacksonquestion.Dog","breed":"Greyhound"},
{"@class":"jacksonquestion.Human","name":"Cheryl"},
{"@class":"jacksonquestion.Human","name":"Timothy"}
]
}
そして、私はそれらをこれらのクラス(すべてjacksonquestion.*
)に逆シリアル化しようとしています:
public class Household {
private Human owner;
private List<Animal> residents;
public Human getOwner() { return owner; }
public void setOwner(Human owner) { this.owner = owner; }
public List<Animal> getResidents() { return residents; }
public void setResidents(List<Animal> residents) { this.residents = residents; }
}
public class Animal {}
public class Dog extends Animal {
private String breed;
public String getBreed() { return breed; }
public void setBreed(String breed) { this.breed = breed; }
}
public class Human extends Animal {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
この構成を使用する:
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
private static class AnimalMixin {
}
//...
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.getDeserializationConfig().addMixInAnnotations(Animal.class, AnimalMixin.class);
Household household = objectMapper.readValue(json, Household.class);
System.out.println(household);
ご覧のとおり、所有者は動物ではなく人間として宣言されているので、@class
通常どおりに省略して、ジャクソンにタイプを推測させたいと思います。
これを実行すると、
org.codehaus.jackson.map.JsonMappingException: Unexpected token (END_OBJECT),
expected FIELD_NAME: missing property '@class' that is to contain type id (for class jacksonquestion.Human)
「所有者」はを指定しないので@class
。
何か案は?私が最初に考えた@JsonTypeInfo
のは、タイプではなくプロパティで使用することでした。 ただし、これを利用してリストの要素タイプに注釈を付けることはできません。 (不正解、回答を参照)