我正在使用Jackson来反序列化一些JSON,并且在尝试对其中一个字段使用自定义反序列化器时遇到了麻烦。
class MyClass
{
private static class SpecialPropertyDeserializer extends JsonDeserializer<SpecialProperty>
{
@Override
public SpecialProperty deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) throws IOException, JsonProcessingException
{
// do some custom deserialisation
}
}
private static class SpecialProperty
{
private String m_foo;
private String m_bar;
@JsonCreator
SpecialProperty(@JsonProperty("foo") String foo,
@JsonProperty("bar") String bar)
{
m_foo = foo;
m_bar = bar;
}
}
private String m_identifier;
private String m_version;
@JsonDeserialize(using = SpecialPropertyDeseializer.class)
private SpecialProperty m_specialProperty;
@JsonCreator
MyClass(@JsonProperty("identifier") String identifier,
@JsonProperty("version") String version,
@JsonProperty("specialProperty") SpecialProperty specialProperty)
{
m_identifier = identifier;
m_version = version;
m_specialProperty = specialProperty;
}
}
这是我要反序列化的JSON:
{
"identifier" : "some-id",
"version" : "1.7",
"specialProperty" : {
"foo" : "str1",
"bar" : "str2"
},
}
我按如下方式调用映射器:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
return objectMapper.readValue(input, MyClass.class);
我观察到以下行为:
SpecialProperty
从代码和JSON中删除所有对它的引用。SpecialProperty
在JSON中,但删除了它的自定义解串器,则它也可以正常工作。的ctorSpecialProperty
被调用。SpecialProperty
被调用,但是自定义反序列化器未被调用。我究竟做错了什么?
@JsonDeserialize
批注可以放在字段,设置器或类上。如果注释的内容是用于设置值的,Jackson将考虑到它。
Eg1@JsonDeserialize
如果使用setter来设置字段的值,它将注意到setter。
Eg2@JsonDeserialize
如果在不使用setter或构造函数的情况下直接设置了该字段,它将注意到一个字段。
除非在字段或setter docs上被更特定的注释所覆盖,否则它将倾向于将其考虑在类中。我认为有关上述细节的文档可能会更清楚。
在您的情况下,您在SpecialProperty
字段上具有注释,但是您正在MyClass
构造函数中设置此字段,因此将其忽略。
在这种情况下,您可以@JsonDeserialize
在课程上移动而不是在字段上移动。在您的情况下,这可能是最简单的解决方案。例如
@JsonDeserialize(using = MyClass.SpecialPropertyDeserializer.class)
private static class SpecialProperty {
或者,您可以完全跳过注释,并在映射器上注册解串器。首先创建SpecialProperty
和SpecialPropertyDeserializer
非私有MyClass
,然后:
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(MyClass.SpecialProperty.class, new MyClass.SpecialPropertyDeserializer());
objectMapper.registerModule(module);
您还可以摆脱的构造函数,MyClass
并且SpecialProperty
将考虑该字段上的当前注释。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句