![](/img/trans.png)
[英]Unexpected Serialization behaviour with configured Jackson Object Mapper
[英]Unexpected serialization behavior with configured Jackson ObjectMapper
我正在使用 Jackson 2.10.5 将同一个java.util.Date
对象序列化三次。
ObjectMapper
。 我看到了时间戳。ObjectMapper
,并重写。 我得到相同的结果。ObjectMapper
,以同样的方式配置它。 我得到了一个不同的结果,类名和 JSON 列表中的时间戳。 该配置旨在告诉ObjectMapper
将除java.util.Date
之外的每个对象的类名作为 JSON 属性包含在内。
所以我有两个问题。 第一个是为什么在第三种情况下日期对象序列化不同? 任何关于以不同方式使用PolymorphicTypeMapper
建议将不胜感激。
第二个是为什么第一个和第二个是相同的(是因为对象映射器有一个缓存(哎哟!)?)。
[编辑:我应该提到这个用例是作为 Jersey 的 JSON 提供程序。 我有一种在启动时生成和配置ObjectMapper
的方法,但是配置 per-write 的(不)能力仅适用于上面的测试代码。]
private PolymorphicTypeValidator getPTV() {
return BasicPolymorphicTypeValidator.builder()
.denyForExactBaseType(Date.class)
.build();
}
@Test
public void serializationTest() {
try {
Date now = new Date();
// Create an object mapper and serialize the date
ObjectMapper om = new ObjectMapper();
String serialized1 = om.writeValueAsString(now); // result: 1605744866827
om.activateDefaultTypingAsProperty(getPTV(), ObjectMapper.DefaultTyping.EVERYTHING, "@class");
String serialized2 = om.writeValueAsString(now); // result: 1605744866827
ObjectMapper om2 = new ObjectMapper();
om2.activateDefaultTypingAsProperty(getPTV(), ObjectMapper.DefaultTyping.EVERYTHING, "@class");
String serialized3 = om2.writeValueAsString(now); // result: ["java.util.Date",1605744866827]
Logger.getLogger(SerializationTest.class).info(serialized1);
Logger.getLogger(SerializationTest.class).info(serialized2);
Logger.getLogger(SerializationTest.class).info(serialized3);
Assert.assertEquals("Unexpected change in serialization 1-2", serialized1, serialized2);
Assert.assertEquals("Unexpected change in serialization 1-3", serialized1, serialized3);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
这是输出:
INFO 2020-11-18 16:14:27,065 [main] <> test.SerializationTest : 1605744866827
INFO 2020-11-18 16:14:27,066 [main] <> test.SerializationTest : 1605744866827
INFO 2020-11-18 16:14:27,066 [main] <> test.SerializationTest : ["java.util.Date",1605744866827]
org.junit.ComparisonFailure: Unexpected change in serialization 1-3
Expected :1605744866827
Actual :["java.util.Date",1605744866827]
阅读文档,即ObjectMapper
的 javadoc,它说(我用粗体突出显示) :
Mapper 实例是完全线程安全的,前提是实例的所有配置都发生在任何读取或写入调用之前。 如果映射器的配置在第一次使用后被修改,更改可能生效也可能不生效,并且配置调用本身可能会失败。 如果您需要使用不同的配置,您有两种主要的可能性:
构造并使用
ObjectReader
进行读取,使用ObjectWriter
进行写入。 这两种类型都是完全不可变的,您可以使用ObjectMapper
工厂方法或读取器/ObjectMapper
器本身自由地创建具有不同配置的新实例。 构建新的ObjectReader
和ObjectWriter
是一个非常轻量级的操作,因此通常适合根据需要在每次调用的基础上创建它们,以配置 JSON 的可选缩进等内容。如果通过
ObjectReader
和ObjectWriter
无法获得特定类型的可配置ObjectWriter
,您可能需要使用多个ObjectMapper
来代替(例如:您不能即时更改混合注释;或者,一组自定义(反)序列化程序) . 为了帮助使用这种用法,您可能需要使用方法copy()
创建具有特定配置的映射器的克隆,并允许在使用之前配置复制的实例。 请注意,copy()
操作与构造一个新的ObjectMapper
实例一样昂贵:如果可能,如果您打算将它们用于多个操作,您仍然应该池化和重用映射器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.