当前位置: 首页 > 知识库问答 >
问题:

在Jackson json序列化中使用条件动态排除POJO属性

洪高阳
2023-03-14

我需要在定义的 POJO 列表中动态排除某些属性。要序列化的主要 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是被忽略,如果忽略id=true,像这样:

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

目前,我已经尝试使用< code>JsonFilter和< code>JacksonJsonViews但无法获得所需的输出。如果能给出实现这一目标的任何指示,我将非常高兴。

共有3个答案

司空学智
2023-03-14

我刚刚看到了罪魁祸首。非常感谢@Alexey和我在一起。经过多次尝试,我发现 Jackson 2.4.2 可能要求我将我的序列化程序放置在它可以使用的模型中。我想知道为什么,但可能是由于 Java 对象序列化要求,杰克逊未能在运行时映射过滤器。我希望塔图能在杰克逊文档中注意到这一点

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 );
             }
         }
      }
    }
}
王兴腾
2023-03-14

我使用的是Jackson 2.4.2。

模型对象是:

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 );
        }
     }
  }
}

注意:模型类在客户端-服务器架构环境中通过网络传递

戚翼
2023-03-14

您应该编写一个自定义的Jackson过滤器,根据其他属性值过滤出POJO属性。您应该重写< code > property filter . serializae sfield()方法来访问序列化对象的实例。这里有一个例子:

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"
} ]
 类似资料:
  • 我有几个具有许多属性的类。这些属性的值将根据某些条件分配。在将值分配给少数属性后,我想序列化对象并仅包括那些具有值分配给它们的道具。 我试过在网上搜索这个,但我找不到任何运气。 任何关于实施这一点的建议都将不胜感激。 更新: 我有一些课程 这些类中属性的值需要根据条件进行分配。分配值后,只需要序列化那些已分配值的属性。 这里,我想只序列化那些被赋值的属性。

  • 问题内容: 我希望能够在使用System.Text.Json.JsonSerializer进行序列化时排除属性。我不想在每个我想做的地方都使用属性。我希望能够通过某种Fluent API定义仅在序列化过程中要排除的属性,目前尚不存在。 我能够找到的唯一选择是定义一个,并将其添加到我传递给Serialize()方法的的Converters列表中,如下所示: 在JsonConverter中,我必须使用

  • 问题内容: 我在Django REST框架中有一个序列化器,定义如下: 现在,我有两个使用上述序列化器的API视图: 一种解决方案是编写两个不同的序列化器。但是必须有一个更简单的解决方案,以有条件地从给定的序列化器中排除字段。 问题答案: 你尝试过这种技术 如果没有,请尝试一下。

  • 问题内容: 我正在使用JSON.NET对对象进行序列化以连接到REST API。我对象中需要序列化为JSON的属性之一具有动态属性名称。如果此属性的struct中包含的值是数字值,则JSON属性为“ type_id”,但是,如果此值是字符串值,则JSON属性名称为“ type_code”。我尝试为此使用自定义,但是在尝试序列化时收到以下消息: “状态为Property的令牌PropertyName

  • 我使用的是JSON。NET来序列化连接到REST API的对象。我的对象中需要序列化为JSON的一个属性具有动态属性名。如果此属性的结构中包含的值是数值,则JSON属性为“type_id”,但如果此值为字符串值,则JSON属性名称为“type_code”。我试图为此使用自定义的,但在尝试序列化时,我收到了一条带有此消息的: "状态属性中的令牌属性名称将导致无效的JSON对象。路径"。" 下面是我的

  • 问题内容: 我使用不同的数据库,并且根据数据库,我需要将“ id”命名为不同的名称。因此,例如在id中被命名为“ @rid” 对于MongoDB,该ID名为“ _id” 我不知道现代数据库开发人员有什么问题,不仅仅是命名id字段“ id” ^^。但是现在我有一个问题。在某些情况下,如何将ID字段动态序列化/反序列化为“ @rid”,在另一种情况下,如何动态序列化/反序列化为“ _id”? 编辑: