我有一堂课,看起来像下面这样
public class MyClass {
private String val1;
private String val2;
private Map<String,Object> context;
// Appropriate accessors removed for brevity.
...
}
我希望能够与Jackson进行往返,从对象到JSON再返回。我可以很好地序列化对象并接收以下输出:
{
"val1": "foo",
"val2": "bar",
"context": {
"key1": "enumValue1",
"key2": "stringValue1",
"key3": 3.0
}
}
我遇到的问题是,由于序列化映射中的值没有任何类型信息,因此无法正确地反序列化它们。例如,在上面的示例中,应将enumValue1反序列化为枚举值,而应反序列化为字符串。我已经看到了基于各种事物的类型的示例,但是在我的场景中,我不知道类型是什么(它们将是我事先不知道的用户生成的对象),所以我需要能够使用键值对序列化类型信息。我如何与杰克逊做到这一点?
作为记录,我使用的是Jackson 2.4.2版。我用来测试往返的代码如下:
@Test
@SuppressWarnings("unchecked")
public void testJsonSerialization() throws Exception {
// Get test object to serialize
T serializationValue = getSerializationValue();
// Serialize test object
String json = mapper.writeValueAsString(serializationValue);
// Test that object was serialized as expected
assertJson(json);
// Deserialize to complete round trip
T roundTrip = (T) mapper.readValue(json, serializationValue.getClass());
// Validate that the deserialized object matches the original one
assertObject(roundTrip);
}
由于这是一个基于Spring的项目,因此将按以下方式创建映射器:
@Configuration
public static class SerializationConfiguration {
@Bean
public ObjectMapper mapper() {
Map<Class<?>, Class<?>> mixins = new HashMap<Class<?>, Class<?>>();
// Add unrelated MixIns
..
return new Jackson2ObjectMapperBuilder()
.featuresToDisable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS)
.dateFormat(new ISO8601DateFormatWithMilliSeconds())
.mixIns(mixins)
.build();
}
}
我认为实现所需目标的最简单方法是使用:
ObjectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
这将在序列化的json中添加类型信息。
这是一个正在运行的示例,您需要适应于Spring:
public class Main {
public enum MyEnum {
enumValue1
}
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
MyClass obj = new MyClass();
obj.setContext(new HashMap<String, Object>());
obj.setVal1("foo");
obj.setVal2("var");
obj.getContext().put("key1", "stringValue1");
obj.getContext().put("key2", MyEnum.enumValue1);
obj.getContext().put("key3", 3.0);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
System.out.println(json);
MyClass readValue = mapper.readValue(json, MyClass.class);
//Check the enum value was correctly deserialized
Assert.assertEquals(readValue.getContext().get("key2"), MyEnum.enumValue1);
}
}
该对象将被序列化为类似于以下内容的对象:
[ "so_27871226.MyClass", {
"val1" : "foo",
"val2" : "var",
"context" : [ "java.util.HashMap", {
"key3" : 3.0,
"key2" : [ "so_27871226.Main$MyEnum", "enumValue1" ],
"key1" : "stringValue1"
} ]
} ]
并且将正确反序列化,并且断言将通过。
顺便说一下,还有更多的方法可以做到这一点,请查看https://github.com/FasterXML/jackson-
docs/wiki/JacksonPolymorphicDeserialization
了解更多信息。
希望对您有所帮助。
问题内容: 我有一个叫做抽象类,然后两个是实现,和。我遇到的问题是,当我将a的其余端点调用到数据库中时,理想情况下,我希望它像将实例传递给REST端点的位置一样。如果不是用一个以上的实现来抽象,那就没问题了,但是由于我有2个,所以我得到了一个错误。 “问题:抽象类型要么需要映射到具体类型,要么具有自定义反序列化器,要么被其他类型信息实例化” 在找到解决方案之后,我找到了一个SO答案,说我可以使用类
我在一个文件中有以下 JSON 当我使用Jackson将其反序列化为Java对象时,我得到以下错误 我正在使用以下代码 object mapper mapper = new object mapper(); 我已经为初始数组使用了类型引用,但如何将类型引用用于对象EnrolledEnrolment内的hashmap。 当它尝试解析第二个数组时抛出错误?有什么想法吗? 谢谢
问题内容: 我正在尝试使用Jakson反序列化嵌套的多态类型。意思是我的顶级类型引用了另一个多态类型,该类型最终由不是抽象的类扩展。这不起作用,并引发异常。 这是我要尝试做的简化示例。 我得到有关抽象类型的标准例外。 让我解释一下我的用例。我有一个描述数据工作流程的Json文档。我在“一级”有一个抽象类型,描述了对单个值的操作。我派生了一堆不是抽象的类,它们实现了常见的操作(我用@JsonSubT
我正在调用一个返回JSON的endpoint,它看起来像这样(在Postman中): 此请求返回的Content-Type头是(与通常的 类来自外部库(编写这个endpoint的人)。无论如何,当我试图通过< code > rest template . exchange()调用这个endpoint时,Jackson都无法将这个JSON反序列化为一个有效的< code>Result类。我正在这样做
问题内容: 我想反序列化JSON对象中的任何未知字段,作为pojo成员的映射中的条目。 例如json 和pojo 有没有办法用杰克逊配置它?如果不是,是否有一种有效的方法编写a 来做到这一点(假设in中的值可以是更复杂但众所周知的一致类型)? 问题答案: 有一个功能和一个注释正好适合此目的。 经过测试,它可以像您的示例一样使用UUID: 它将像这样工作: 同样,更常见的类型(例如字符串)也可以工作
问题内容: 这是我的Java代码,用于反序列化,我正在尝试将json字符串转换为java对象。为此,我使用了以下代码: 和我的product.java类 我收到以下错误。 帮我解决这个问题 问题答案: 似乎您正在尝试从JSON读取一个实际描述数组的对象。Java对象使用花括号映射到JSON对象,但是您的JSON实际上以方括号指定一个数组开始。 您实际拥有的是一个。为了描述泛型类型,由于Java的类