我正在使用杰克逊(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);
我已经观察到以下行为:
- 没有特殊财产,一切都可以正常工作 - 即删除全部来自代码和JSON的
SpecialProperty
的引用。 - 如果我在JSON中包括
SpecialProperty
,但请删除自定义避难所为此,它也可以正常工作。ctorSpecialProperty
称为。 - 使用自定义避难所,它不起作用。
SpecialProperty
的CTOR被调用,但自定义避难所不是。
我在做什么错?
@JsonDeserialize
注释可以放置在字段,设置器或类上。如果注释是设置值的用途,杰克逊将考虑到它。
例如,如果使用设置器设置字段值,则它将在设置器上注意到@JsonDeserialize
。
,例如,如果在不使用设置器或构造函数的情况下直接设置此字段,则会在字段上注意到@JsonDeserialize
。
,如果它在课堂上,除非它被字段或设置器文档上的更具体的注释所覆盖,否则它会考虑到它。我认为这些文档在上述详细信息上可能更清晰。
在您的情况下,您可以在SpecialProperty
字段上进行注释,但是您将在MyClass
构造函数中设置此字段,因此它被忽略了。
在这种情况下,您可以将@JsonDeserialize
移到类而不是字段上。在您的情况下,这可能是最简单的解决方案。例如
@JsonDeserialize(using = MyClass.SpecialPropertyDeserializer.class)
private static class SpecialProperty {
,也可以完全跳过注释,然后在映射器上注册避难所。首先在MyClass
中制作SpecialProperty
和SpecialPropertyDeserializer
非私有,然后:
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(MyClass.SpecialProperty.class, new MyClass.SpecialPropertyDeserializer());
objectMapper.registerModule(module);
您还可以考虑MyClass
的构造函数,并且将考虑SpecialProperty
字段的当前注释。