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

使用jackson序列化时有条件地跳过对象

包建义
2023-03-14

我有一门课像

interface IHideable {
   boolean isHidden();
}

class Address implements IHideable {
    private String city;
    private String street;
    private boolean hidden;
}

class PersonalInfo implements IHideable {
    private String name;
    private int age;
    private boolean hidden;
}

我想在我的Web服务中序列化IHideable列表;但是过滤掉任何将隐藏字段设置为true的对象。

基本上给出了一个物体列表,比如

[
{'city 1','street 1',false},
{'city 2','street 2',true},
{'city 3','street 3',false}
]

我希望输出为

[
  {
    city:'city 1',
    street:'street 1'
  },
  {
    city:'city 3',
    street:'street 3'
  }
]

我尝试了以下实现

class ItemSerializer extends JsonSerializer<IHideable> {  
    @Override
    public void serialize(IHideable value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {

        if (!value.isHidden()) {
            jgen.writeStartObject();
            jgen.writeString("city", value.city);
            jgen.writeString("street", value.street);
            jgen.writeEndObject();
        }
    }
}

但是编写的writeString方法是特定于Address类的。当我在那里使用writeObject时,它抛出stackoverflow异常。我可以使用一些通用writeObject方法来编写实现IHideable()的任何对象吗?对于默认/自定义序列化,这是否可行?

共有1个答案

龙星辰
2023-03-14

您可以使用BeanSerializerModifierIHideable类型注册序列化程序,并获取对默认bean序列化程序的引用,正如本问题中讨论的那样。

在序列化程序中,检查ishiden标志,如果未设置该标志,则使用默认序列化程序序列化实例。这个技巧应该适用于实现IHideable接口的任何类型。以下是一个例子:

public class JacksonHide {
    @JsonIgnoreProperties("hidden")
    public static interface IHideable {
        boolean isHidden();
    }

    public static class Address implements IHideable {
        public final String city;
        public final String street;
        public final boolean hidden;

        public Address(String city, String street, boolean hidden) {
            this.city = city;
            this.street = street;
            this.hidden = hidden;
        }

        @Override
        public boolean isHidden() {
            return hidden;
        }
    }

    public static class PersonalInfo implements IHideable {
        public final String name;
        public final int age;
        public final boolean hidden;

        public PersonalInfo(String name, int age, boolean hidden) {
            this.name = name;
            this.age = age;
            this.hidden = hidden;
        }

        @Override
        public boolean isHidden() {
            return hidden;
        }
    }

    private static class MyBeanSerializerModifier extends BeanSerializerModifier {
        @Override
        public JsonSerializer<?> modifySerializer(SerializationConfig config,
                                                  BeanDescription beanDesc,
                                                  JsonSerializer<?> serializer) {
            if (IHideable.class.isAssignableFrom(beanDesc.getBeanClass())) {
                return new MyIHideableJsonSerializer((JsonSerializer<IHideable>) serializer);
            }
            return super.modifySerializer(config, beanDesc, serializer);
        }

        private static class MyIHideableJsonSerializer extends JsonSerializer<IHideable> {
            private final JsonSerializer<IHideable> serializer;

            public MyIHideableJsonSerializer(JsonSerializer<IHideable> serializer) {
                this.serializer = serializer;
            }

            @Override
            public void serialize(IHideable value,
                                  JsonGenerator jgen,
                                  SerializerProvider provider) throws IOException {
                if (!value.isHidden()) {
                     serializer.serialize(value, jgen, provider);
                }

            }
        }
    }

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.setSerializerModifier(new MyBeanSerializerModifier());
        mapper.registerModule(module);

        PersonalInfo p1 = new PersonalInfo("John", 30, false);
        PersonalInfo p2 = new PersonalInfo("Ivan", 20, true);
        Address a1 = new Address("A", "B", false);
        Address a2 = new Address("C", "D", true);

        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString
                (Arrays.asList(p1, p2, a1, a2)));
    }

}

输出:

[ {
  "name" : "John",
  "age" : 30
}, {
  "city" : "A",
  "street" : "B"
} ]
 类似资料:
  • 我想要的是有条件地为类的对象使用默认BeanSerializer: 我曾经尝试过做这样的事情: 但是这调用MyCustomSerializer的方法,我有永无止境的递归。我怎么能得到适当的序列化对象,我可以用普通bean序列化?

  • 使用Jackson将JSON响应反序列化为DTO。 使用Gson或Jackson反序列化JSON时忽略空字段 他们仍然从那个不规则的JSON对象创建一个对象。 这意味着我需要遍历这个列表,并通过实现一个清理方法删除所有不具有属性“value”的对象。 我的带有Jackson注释的DTO: 给定JSON响应的结果是初始化了3个DTOs,而不是4个。

  • 我有一个具有两个属性的JSON对象:“key”(字符串)和“value”(可以反序列化为Java bean)。 问题是,给定一个这样的物体列表,我能把它反序列化为一张地图吗? 当前使用Jackson-databind 2.1

  • 我目前正在开发一个Java web应用程序,它使用Magento REST API公开的JSON数据。api返回的数据示例如下: 我的应用程序中有一个Java类,如下所示: 我想对数据进行反序列化,并将其转换为,但我总是得到以下错误: 这是我用来将JSON响应反序列化为ArrayList的语句行: 有人能分享一些见解吗?我看到一些例子,返回的JSON对象前面没有任何ID。那是因为我做错了什么吗?非

  • 主要内容:1 编写核心类,2 运行测试本文讲解如何将一个Java对象序列化为一个json文件,然后读取该json文件读取回对象。在下面的示例中,我们创建Student类。使用Jackson存储到一个student.json文件,该文件拥有Student对象的JSON表示形式。 1 编写核心类 MainApp: 2 运行测试

  • 我需要一个自定义反序列化器来在复杂的POJO中转换字符串。反序列化工作直到使用反序列化器:特别是使用自定义反序列化器时,我的对象的非对象属性不会序列化。 我有一个restful Web服务,它有一个pojo作为参数。 所以我的类PreentivoWs需要一个方法。这里是类定义: 在jsonObject中,我有一个枚举定义为 但此对象需要转换反序列化程序: 并在财产上标注: fromString方法