使用 Jackson 将 JSON 反序列化为多态类型

编程入门 行业动态 更新时间:2024-10-28 18:30:12
本文介绍了使用 Jackson 将 JSON 反序列化为多态类型 - 一个完整的例子给了我一个编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试完成程序员 Bruce 的教程,该教程应该允许对多态 JSON 进行反序列化.

I am attempting to work through a tutorial from Programmer Bruce that is supposed to allow the deserialization of polymorphic JSON.

可以在此处找到完整列表程序员 Bruce 教程(顺便说一句,很棒的东西)

The complete list can be found here Programmer Bruce tutorials (Great stuff btw)

我已经完成了前五个没有问题,但我在最后一个(示例 6)上遇到了障碍,这当然是我真正需要开始工作的一个.

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

ObjectMapper 类型中的 readValue(JsonParser, Class) 方法不适用于参数 (ObjectNode, Class)

The method readValue(JsonParser, Class) in the type ObjectMapper is not applicable for the arguments (ObjectNode, Class)

这是由代码块引起的

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); } }

具体按行

return mapper.readValue(root,animalClass);

return mapper.readValue(root, animalClass);

以前有没有人遇到过这种情况,如果有,有解决方案吗?

Has anyone run into this before and if so, was there a solution?

我很感激任何人可以提供的任何帮助提前致谢乔恩 D.

I'd appreciate any help anyone can give Thanks in advance Jon D.

推荐答案

正如所承诺的,我正在举一个关于如何使用注解来序列化/反序列化多态对象的示例,我将这个示例基于 Animal您正在阅读的教程中的课程.

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.

首先你的 Animal 类和子类的 Json 注释.

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; } }

然后是你的子类,Dog 和 Cat.

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; }

如您所见,Cat 和Dog 没有什么特别的,唯一知道它们的是abstract 类Animal,因此在反序列化时,您将定位到 Animal 并且 ObjectMapper 将返回实际实例,如您在以下测试中所见:

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(); } } }

运行Test类后的输出:

{"@type":"Dog","name":"ruffus","breed":"english shepherd"}

反序列化的dogJson类:Dog

{"@type":"Cat","name":"goya","favoriteToy":"mice"}

反序列化的catJson类:Cat

希望这会有所帮助,

何塞·路易斯

更多推荐

使用 Jackson 将 JSON 反序列化为多态类型

本文发布于:2023-11-07 14:33:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1566712.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:序列   类型   多态   Jackson   JSON

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!