2014-09-01 35 views
1

我有一個要求來動態地排除定義的POJO列表中的某個屬性。 主要POJO要序列是:使用條件來動態地排除Jackson json序列化中的POJO屬性

public class Foo 
{ 
    List<Bar> bar; 

    public void setBar(List<Bar> bar) 
    { 
     this.bar = bar; 
    } 

    public List<Bar> getBar() 
    { 
     return this.bar; 
    } 

    public static class Bar 
    { 
     private int id; 
     private boolean ignoreId; 
     private String name; 

     public void setId(int id) 
     { 
      this.id = id; 
     } 

     public int getId() 
     { 
      return this.id; 
     } 

     public void setIgnoreId(boolean ignoreId) 
     { 
      this.ignoreId = ignoreId; 
     } 

     public boolean isIgnoreId() 
     { 
      return this.ignoreId; 
     } 

     public void setName(String name) 
     { 
      this.name = name; 
     } 

     public String getName() 
     { 
      return this.name; 
     } 
    } 
} 

ID是被忽略的,如果ignoreId =真,就像這樣:

[ 
    { "id": "1", "name": "one" }, 
    { "name": "two" } 
    { "name": "three" } 
    { "id": "4", "name": "four" } 
] 

此刻,我一直在使用JsonFilterJacksonJsonViews嘗試,但couldn」 t獲得所需的輸出。 我會很高興,如果任何指針可以實現這一目標。

+0

應該在這種情況下使用JsonFilter。你能否描述爲什麼過濾器不適合你? – 2014-09-01 12:03:06

+0

@AlexeyGavrilov,我創建像這樣一個邏輯: '@JsonFilter( 「Exclude.Id」) 類PropertyFilterMixIn {}' 如果我已經'設置 ignorableFieldNames =新的ArrayList ()。新增( 「ID」 );' 我可以這樣做: 'FilterProvider filters = new SimpleFilterProvider()。addFilter(「Exclude.Id」,SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames)); ObjectWriter writer = mapper.writer(filters); System.out.println(writer.writeValueAsString(new Foo())); 我的挑戰是動態地將'id'添加到'ignorableFieldNames []'當且僅當'ignoreId'爲真 – Damilola 2014-09-01 14:24:26

回答

1

你應該編寫一個自定義的Jackson filter,它會根據其他屬性值過濾出POJO屬性。您應該重寫PropertyFilter.serializeAsField()方法以訪問序列化對象的實例。這裏有一個例子:

public class JacksonFilter2 { 
    @JsonFilter("filter") 
    public static class Bar { 
     public final int id; 
     @JsonIgnore 
     public final boolean ignoreId; 
     public final String name; 

     public Bar(int id, boolean ignoreId, String name) { 
      this.id = id; 
      this.ignoreId = ignoreId; 
      this.name = name; 
     } 
    } 

    public static class ExcludeIdFilter extends SimpleBeanPropertyFilter { 

     @Override 
     protected boolean include(BeanPropertyWriter writer) { 
      return true; 
     } 

     @Override 
     protected boolean include(PropertyWriter writer) { 
      return true; 
     } 

     @Override 
     public void serializeAsField(Object pojo, 
            JsonGenerator jgen, 
            SerializerProvider provider, 
            PropertyWriter writer) throws Exception { 
      if (pojo instanceof Bar 
        && "id".equals(writer.getName()) 
        && ((Bar) pojo).ignoreId) { 
       writer.serializeAsOmittedField(pojo, jgen, provider); 
      } else { 
       super.serializeAsField(pojo, jgen, provider, writer); 
      } 
     } 
    } 

    public static void main(String[] args) throws JsonProcessingException { 
     List<Bar> bars = Arrays.asList(new Bar(1, false, "one"), new Bar(2, true, "two")); 
     ObjectMapper mapper = new ObjectMapper(); 
     mapper.setFilters(new SimpleFilterProvider().addFilter("filter", new ExcludeIdFilter())); 
     System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(bars)); 
    } 

} 

輸出:

[ { 
    "id" : 1, 
    "name" : "one" 
}, { 
    "name" : "two" 
} ] 
+0

謝謝Alexey。我似乎越來越'沒有過濾器配置ID ...' – Damilola 2014-09-01 16:46:12

+0

@Damilola上面的例子適用於我。你在哪個傑克遜版本上?你能用你的過濾器代碼更新你的問題嗎? – 2014-09-01 18:12:20

+0

它看起來像我的問題類似於Tatu [here](http:// markmail)的討論。org/message/ffhut2sigegulhkx#query:+ page:1 + mid:dygkifj7tv72bypx + state:results) – Damilola 2014-09-01 19:44:16

0

我使用傑克遜2.4.2。

Model對象是:

public class PostProject 
{ 
    /* The field template of this project */ 
    private List<FieldTemplateObject> field_templates; 

    /** 
    * @author Damilola Okuboyejo 
    */ 
    @JsonFilter("FieldTemplateIdFilter") 
    public static class FieldTemplateObject 
    { 
     private int  id; 
     private boolean is_inherited; 
     private String item_type; 

     /** 
     * @return the id 
     */ 
     public int getId() 
     { 
     return id; 
     } 

     /** 
     * @param id 
     *   the id to set 
     */ 
     public void setId(int id) 
     { 
     this.id = id; 
     } 

     /** 
     * @return the is_inherited 
     */ 
     public boolean isIs_inherited() 
     { 
     return is_inherited; 
     } 

     /** 
     * @param is_inherited 
     *   the is_inherited to set 
     */ 
     public void setIs_inherited(boolean is_inherited) 
     { 
     this.is_inherited = is_inherited; 
     } 

     /** 
     * @return the item_type 
     */ 
     public String getItem_type() 
     { 
     if(item_type == null) 
     { 
      item_type = PostProject.item_type; 
     } 
     return item_type; 
     } 

     /** 
     * @param item_type 
     *   the item_type to set 
     */ 
     public void setItem_type(String item_type) 
     { 
     this.item_type = item_type; 
     } 
    } 
} 

MYY串行就像這樣:

public static class ModelFieldSerializer extends SimpleBeanPropertyFilter 
{ 
    @Override 
    protected boolean include(BeanPropertyWriter writer) 
    { 
    return true; 
    } 

    @Override 
    protected boolean include(PropertyWriter writer) 
    { 
    return true; 
    } 

    @Override 
    public void serializeAsField(Object pPojo, JsonGenerator pJgen, 
     SerializerProvider pProvider, PropertyWriter pWriter) 
     throws Exception 
    { 
    if(pPojo instanceof FieldTemplateObject) 
    { 
     if(("id".equals(pWriter.getName())) 
       && ((FieldTemplateObject) pPojo).isIs_inherited()) 
     { 
      pWriter.serializeAsOmittedField(pPojo, pJgen, pProvider); 
     } 
     else 
     { 
      super.serializeAsField(pPojo, pJgen, pProvider, pWriter); 
     } 
    } 
    } 
} 

注意:模型類是通過客戶端 - 服務器架構ENV

+0

你能告訴你如何爲ObjectMapper註冊你的過濾器嗎?將代碼移到問題中也是有道理的,因爲這不是真正的答案。 – 2014-09-02 07:15:29

+0

'vJsonMapper.setFilters(new SimpleFilterProvider()。addFilter( 「FieldTemplateIdFilter」, new ModelFieldSerializer()));' – Damilola 2014-09-02 07:23:41

+0

是否在設置過濾器之前或之後使用ObjectMapper?你能做出一個完整的課程來重現你的問題嗎?我的答案中的代碼是否適合您? – 2014-09-02 07:46:03

0

我通過網絡傳遞只是看到了罪魁禍首。 非常感謝@Alexey與我一起住在這裏。經過多次嘗試之後,我發現傑克遜2.4.2可能要求我將序列器放在它可以使用的模型中。我想知道爲什麼,但可能是由於Java對象序列化的要求,傑克遜未能在運行時映射過濾器。我希望Tatu會在Jackson文檔中注意到這一點

public class PostProject 
{ 
    /* The field template of this project */ 
    private List<FieldTemplateObject> field_templates; 

    /** 
    * @author Damilola Okuboyejo 
    */ 
    @JsonFilter("FieldTemplateIdFilter") 
    public static class FieldTemplateObject 
    { 
     private int  id; 
     private boolean is_inherited; 
     private String item_type; 

     /** 
     * @return the id 
     */ 
     public int getId() 
     { 
     return id; 
     } 

     /** 
     * @param id 
     *   the id to set 
     */ 
     public void setId(int id) 
     { 
     this.id = id; 
     } 

     /** 
     * @return the is_inherited 
     */ 
     public boolean isIs_inherited() 
     { 
     return is_inherited; 
     } 

     /** 
     * @param is_inherited 
     *   the is_inherited to set 
     */ 
     public void setIs_inherited(boolean is_inherited) 
     { 
     this.is_inherited = is_inherited; 
     } 

     /** 
     * @return the item_type 
     */ 
     public String getItem_type() 
     {   
     return item_type; 
     } 

     /** 
     * @param item_type 
     *   the item_type to set 
     */ 
     public void setItem_type(String item_type) 
     { 
     this.item_type = item_type; 
     } 
    } 

    public static class ModelFieldSerializer extends SimpleBeanPropertyFilter 
    { 
     @Override 
     protected boolean include(BeanPropertyWriter writer) 
     { 
     return true; 
     } 

     @Override 
     protected boolean include(PropertyWriter writer) 
     { 
     return true; 
     } 

     @Override 
     public void serializeAsField(Object pPojo, JsonGenerator pJgen, 
      SerializerProvider pProvider, PropertyWriter pWriter) 
      throws Exception 
     { 
     if(pPojo instanceof FieldTemplateObject) 
     { 
      boolean vAllowId = ((FieldTemplateObject) pPojo).isIs_inherited(); 
      if(!vAllowId && ("id".equals(pWriter.getName()))) 
      { 
       return; // skip the id property 
      } 
      else 
      { 
       super.serializeAsField(pPojo, pJgen, pProvider, pWriter); 
      } 
     } 
     } 
    } 
} 
+0

Java對象序列化要求不適用於Jackson。你應該遇到別的東西。如果您可以將最小化的可重現樣本代碼發佈到GitHub上,我會試着跟進,否則我沒有線索。 – 2014-09-02 09:47:19

+0

@Alexey我剛剛發佈了一個可縮放的可複製版本[GitHub](https://github.com/FasterXML/jackson-databind/issues/532) – Damilola 2014-09-02 10:45:34

相關問題