使用Jackson

时间:2017-06-02 10:56:36

标签: java json jackson deserialization json-deserialization

我正在使用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);

我发现了以下行为:

  1. 没有特殊属性,一切正常 - 即全部删除 从代码和JSON中引用SpecialProperty
  2. 如果我在JSON中包含SpecialProperty但删除了自定义 它的反序列化器然后它也可以正常工作。 ctor for SpecialProperty被称为。{/ li>
  3. 使用自定义反序列化程序它不起作用。 SpecialProperty的ctor被调用,但自定义反序列化器不被调用。
  4. 我做错了什么?

1 个答案:

答案 0 :(得分:1)

#+ echo = False import pweave pweave.rcParams["chunk"]["defaultoptions"].update({'echo' : False, 'f_pos' : "h!"}) 注释可以放在字段,setter或类上。如果注释的内容是用于设置值的内容,Jackson会将其考虑在内。

E.g.1如果它使用setter来设置字段的值,它会在setter上注意到@JsonDeserialize

E.g.2如果字段直接设置此字段而不使用setter或构造函数,它会注意到@JsonDeserialize

除非它被字段或设置器docs上的更具体的注释覆盖,否则它会在课程中考虑它。我认为上述细节可以使文档更加清晰。

在您的情况下,您在@JsonDeserialize字段上有注释,但您在SpecialProperty构造函数中设置了此字段,因此忽略了该字段。

在这种情况下,您可以在课程上而不是在字段上移动MyClass。在您的情况下,这可能是最简单的解决方案。 E.g。

@JsonDeserialize

或者您可以完全跳过注释并在映射器上注册反序列化器。首先在@JsonDeserialize(using = MyClass.SpecialPropertyDeserializer.class) private static class SpecialProperty { 中将SpecialPropertySpecialPropertyDeserializer设为非私人,然后:

MyClass

您还可以删除ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(MyClass.SpecialProperty.class, new MyClass.SpecialPropertyDeserializer()); objectMapper.registerModule(module); 的构造函数,并考虑MyClass字段上的当前注释。