2017-06-02 182 views
3

我正在使用Jackson反序列化一些JSON,并且在尝试对其中一个字段使用自定义反序列化器时遇到了一些麻烦。使用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,但删除自定义 解串器,那么它也可以正常工作。调用 SpecialProperty的ctor。
  3. 使用自定义解串器它不起作用。调用SpecialProperty的ctor被调用,但是自定义解串器没有。

我在做什么错?

+0

您的specialProperty是否是对象?如果是,那么它是什么样的? –

+0

这是一个对象,是的。它由'SpecialProperty'类表示。 – ksl

回答

1

@JsonDeserialize注释可以放在字段,设置者或类上。如果注释是用来设置值的话,Jackson会考虑它。

E.g.1如果它使用setter来设置字段的值,它将通过setter注意到@JsonDeserialize

E.g.2如果它在不使用setter或构造函数的情况下直接设置此字段,它将在字段上注意到@JsonDeserialize

如果它在某个类上,它将会考虑到它,除非它被字段或设置器docs上更具体的注释覆盖。我认为文件可以在上述细节上更清楚。

在你的情况下,你对SpecialProperty字段有注释,但是你在MyClass构造函数中设置这个字段,所以它被忽略。

在这种情况下,您可以在类上移动@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构造和当前注释在SpecialProperty场将被考虑在内。

相关问题