2017-06-02 158 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場將被考慮在內。

相關問題