解析JSON与Jackson到多态类型 - 一个完整的例子给我一个编译错误 [英] Deserialize JSON with Jackson into Polymorphic Types - A Complete Example is giving me a compile error
问题描述
我试图通过一个来自程序员Bruce的教程,该教程应该允许多态JSON的反序列化。
完整的列表可以在这里找到
程序员Bruce教程(Great stuff btw)
我已经完成了前五个没有问题,但我打了一个最后一个(实例6),当然是我真正需要工作的一个。
我在编译时收到以下错误
ObjectMapper类型中的readValue(JsonParser,Class)方法不适用于参数(ObjectNode,Class)
并且它是由代码块引起的
deserialize(
JsonParser jp,DeserializationContext ctxt)
throws IOException,JsonProcessingException
{
ObjectMapper mapper =(ObjectMapper)jp.getCodec();
ObjectNode root =(ObjectNode)mapper.readTree(jp);
Class< ;? extends Animal> animalClass = null;
Iterator< Entry< String,JsonNode>> elementsIterator =
root.getFields();
while(elementsIterator.hasNext())
{
Entry< String,JsonNode> element = elementsIterator.next();
String name = element.getKey();
if(registry.containsKey(name))
{
animalClass = registry.get(name);
break;
}
}
if(animalClass == null)return null;
return mapper.readValue(root,animalClass);
}
}
特别按行
return mapper.readValue(root,animalClass);
如果是这样,是否有解决方案?
我会感谢任何人可以给任何帮助
感谢提前
Jon D 。
如所承诺的,我将举例说明如何使用注释来序列化/反序列化多态对象,
首先,您的动物
类与子类的Json注释。
import com.fasterxml.jackson.annotation。 JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes({
@ JsonSubTypes.Type(value = Dog.class,name =Dog),
@ JsonSubTypes.Type(value = Cat.class,name =Cat)}
)
public abstract class Animal {
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
然后你的子类 Dog
和 Cat
。
public class Dog extends Animal {
private String breed;
public Dog(){
}
public Dog(String name,String breed){
setName(name);
setBreed(breed);
}
public String getBreed(){
return breed;
}
public void setBreed(String breed){
this.breed = breed;
}
}
public class Cat extends Animal {
public String getFavoriteToy(){
return favoriteToy;
}
public Cat(){}
public Cat(String name,String favoriteToy){
setName(name);
setFavoriteToy(favoriteToy);
}
public void setFavoriteToy(String favoriteToy){
this.favoriteToy = favoriteToy;
}
private String favoriteToy;
}
正如你所看到的, Cat
和 Dog
,唯一知道它们的是 abstract
class Animal
,因此在反序列化时,您将定位到 Animal
和 ObjectMapper
将返回实际的实例,如下面的测试所示:
public class Test {
public static void main(String [] args){
ObjectMapper objectMapper = new ObjectMapper();
Animal myDog = new Dog(ruffus,english shepherd);
Animal myCat = new Cat(goya,mice);
try {
String dogJson = objectMapper.writeValueAsString(myDog);
System.out.println(dogJson);
Animal deserializedDog = objectMapper.readValue(dogJson,Animal.class);
System.out.println(Deserialized dogJson Class:+ deserializedDog.getClass()。getSimpleName());
String catJson = objectMapper.writeValueAsString(myCat);
Animal deseriliazedCat = objectMapper.readValue(catJson,Animal.class);
System.out.println(Deserialized catJson Class:+ deseriliazedCat.getClass()。getSimpleName());
} catch(Exception e){
e.printStackTrace();
}
}
}
运行测试
类:
{@ type:Dog
反序列化的dogJson类:Dog
{@ type:Cat,name:goya,favoriteToy:小鼠}
反序列化的catJson类:Cat
希望这有助于
Jose Luis
I am attempting to work through a tutorial from Programmer Bruce that is supposed to allow the deserialization of polymorphic JSON.
The complete list can be found here Programmer Bruce tutorials (Great stuff btw)
I have worked through the first five with no problems but I have hit a snag on the last one (Example 6), which of course is the one I really need to get working.
I am getting the following error at compile time
The method readValue(JsonParser, Class) in the type ObjectMapper is not applicable for the arguments (ObjectNode, Class)
and it's being caused by the chunk of code
public Animal deserialize(
JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
ObjectNode root = (ObjectNode) mapper.readTree(jp);
Class<? extends Animal> animalClass = null;
Iterator<Entry<String, JsonNode>> elementsIterator =
root.getFields();
while (elementsIterator.hasNext())
{
Entry<String, JsonNode> element=elementsIterator.next();
String name = element.getKey();
if (registry.containsKey(name))
{
animalClass = registry.get(name);
break;
}
}
if (animalClass == null) return null;
return mapper.readValue(root, animalClass);
}
}
Specifically by the line
return mapper.readValue(root, animalClass);
Has anyone run into this before and if so, was there a solution?
I'd appreciate any help anyone can give Thanks in advance Jon D.
As promised, I'm putting an example for how to use annotations to serialize/deserialize polymorphic objects, I based this example in the Animal
class from the tutorial you were reading.
First of all your Animal
class with the Json Annotations for the subclasses.
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat") }
)
public abstract class Animal {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Then your subclasses, Dog
and Cat
.
public class Dog extends Animal {
private String breed;
public Dog() {
}
public Dog(String name, String breed) {
setName(name);
setBreed(breed);
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
}
public class Cat extends Animal {
public String getFavoriteToy() {
return favoriteToy;
}
public Cat() {}
public Cat(String name, String favoriteToy) {
setName(name);
setFavoriteToy(favoriteToy);
}
public void setFavoriteToy(String favoriteToy) {
this.favoriteToy = favoriteToy;
}
private String favoriteToy;
}
As you can see, there is nothing special for Cat
and Dog
, the only one that know about them is the abstract
class Animal
, so when deserializing, you'll target to Animal
and the ObjectMapper
will return the actual instance as you can see in the following test:
public class Test {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
Animal myDog = new Dog("ruffus","english shepherd");
Animal myCat = new Cat("goya", "mice");
try {
String dogJson = objectMapper.writeValueAsString(myDog);
System.out.println(dogJson);
Animal deserializedDog = objectMapper.readValue(dogJson, Animal.class);
System.out.println("Deserialized dogJson Class: " + deserializedDog.getClass().getSimpleName());
String catJson = objectMapper.writeValueAsString(myCat);
Animal deseriliazedCat = objectMapper.readValue(catJson, Animal.class);
System.out.println("Deserialized catJson Class: " + deseriliazedCat.getClass().getSimpleName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output after running the Test
class:
{"@type":"Dog","name":"ruffus","breed":"english shepherd"}
Deserialized dogJson Class: Dog
{"@type":"Cat","name":"goya","favoriteToy":"mice"}
Deserialized catJson Class: Cat
Hope this helps,
Jose Luis
这篇关于解析JSON与Jackson到多态类型 - 一个完整的例子给我一个编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!