2016-06-24 41 views
0

我有由,我映射到的POJO,然後在收集存儲結構的一個大的JSON文件的映射。結構與此類似:自傑克遜解串器忽略某些對象

[ 
{ 
    "id": 1234, 
    "file": "C:\\Programs\\Program1.exe", 
    "exists": true 
} 
{ 
    "id": 5678, 
    "file": "C:\\Programs\\Program2.exe", 
    "exists": false 
} 
... 
] 

使用Jackson streaming API我已經讀取了所有這些結構,併成功將POJO存儲在Collection中。我的POJO類看起來是這樣的:

public class Programs 
{ 
    @JsonProperty("id") 
    private Integer id; 

    @JsonProperty("file") 
    private String file; 

    @JsonProperty("exists") 
    private Boolean exists; 

    @JsonGetter("id") 
    public Integer getId() 
    { 
     return id; 
    } 

    @JsonGetter("file") 
    public String getFile() 
    { 
     return file; 
    } 

    @JsonGetter("exists") 
    public Boolean getExists() 
    { 
     return exists; 
    } 
} 

不過,我想省略過程,以便沒有POJO爲他們創造了有史以來反序列化過程有"exists"設置爲false任何結構。所以我寫了一個自定義解串器的這個幫助,所以質疑[How do I call the default deserializer from a custom deserializer in Jackson],我重寫deserialize看起來像:

@Override 
public Programs deserialize(JsonParser parser, DeserializationContext context) 
    throws IOException 
{ 
    Programs programs = (Programs)defaultDeserializer.deserialize(parser, context); 

    if (!programs.getExists()) 
    { 
     throw context.mappingException("[exists] value is false."); 
    } 
    return programs; 
} 

然而,當我運行一些單元測試,我得到以下錯誤:

"Can not deserialize instance of java.util.ArrayList out of START_OBJECT token" 
message was "Class com.myprogram.serializer.ProgramsJsonDeserializer 
has no default (no arg) constructor" 

(添加無參數的構造函數給出了錯誤說StdDeserializer沒有默認的構造函數)。

這是正確的做法,以實現什麼,我試圖做的?而且沒有人知道爲什麼我收到此錯誤信息?

回答

1

I want to omit any structures that have "exists" set to false during the deserialization process so that no POJO is ever created for them.

,我認爲你的目標是獲取Programs實例的列表,只有exists設置爲true derserialization後。一個定製的CollectionDeserializer來過濾那些不需要的情況下可能會有幫助:

public class ProgramsCollectionHandler extends SimpleModule { 
    private static class ProgramsCollectionDeserializer extends CollectionDeserializer { 

     public ProgramsCollectionDeserializer(CollectionDeserializer deserializer) { 
      super(deserializer); 
     } 

     private static final long serialVersionUID = 1L; 

     @Override 
     public Collection<Object> deserialize(JsonParser parser, DeserializationContext context) 
       throws IOException, JsonProcessingException { 
      Collection<Object> result = super.deserialize(parser, context); 
      Collection<Object> filteredResult = new ArrayList<Object>(); 
      for (Object o : result) { 
       if (o instanceof Programs) { 
        final Programs programs = (Programs) o; 
        if (programs.exists) { 
         filteredResult.add(programs); 
        } 
       } 
      } 
      return filteredResult; 
     } 

     @Override 
     public CollectionDeserializer createContextual(
       DeserializationContext context, 
       BeanProperty property) throws JsonMappingException { 
      return new ProgramsCollectionDeserializer(super.createContextual(context, property)); 
     } 
    } 

    private static final long serialVersionUID = 1L; 

    @Override 
    public void setupModule(Module.SetupContext context) { 
     super.setupModule(context); 
     context.addBeanDeserializerModifier(new BeanDeserializerModifier() { 
      @Override 
      public JsonDeserializer<?> modifyCollectionDeserializer(
        DeserializationConfig config, CollectionType type, 
        BeanDescription beanDesc, JsonDeserializer<?> deserializer) { 
       if (deserializer instanceof CollectionDeserializer) { 
        return new ProgramsCollectionDeserializer(
          (CollectionDeserializer) deserializer); 
       } else { 
        return super.modifyCollectionDeserializer(config, type, beanDesc, 
          deserializer); 
       } 
      } 
     }); 
    } 
} 

之後,你可以將它註冊到你的對象映射:

ObjectMapper mapper = new ObjectMapper(); 
mapper.registerModule(new ProgramsCollectionHandler()); 

"Can not deserialize instance of java.util.ArrayList out of START_OBJECT token" message was "Class com.myprogram.serializer.ProgramsJsonDeserializer has no default (no arg) constructor" (Adding a no arg constructor gives the error that StdDeserializer does not have a default constructor.)

這可能是因爲你的構造不能被訪問。例如,您解串器被實現爲一個非靜態內部類。

+0

非常感謝,這似乎做的伎倆! – MeanwhileInHell