使用jackson序列化时有条件地跳过对象 [英] Skip objects conditionally when serializing with jackson

查看:381
本文介绍了使用jackson序列化时有条件地跳过对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类

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

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

I want to serialize a List of IHideable in my web service; but filter out any object which has the hidden field set to true.

基本上给出一个对象列表,如

Basically given with a list of objects like

[
{'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()的对象吗?
这是否可以使用jackson默认/自定义序列化?

But the writeString methods written are specific for Address class. When i use writeObject there it throws stackoverflow exception. Can I use some generic writeObject method which Can write any object which implements IHideable()? Is this possible with jackson default/custom serialization?

推荐答案

您可以使用 BeanSerializerModifier 为<$ c注册序列化程序$ c> IHideable 类型并获取对默认bean序列化程序的引用,如这个问题。

You can use BeanSerializerModifier to register a serializer for IHideable types and get the reference to the default bean serializer as it was discussed in this question.

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

In your serializer you check the isHidden flag and if it is not set serialize the instance using the default serializer. That trick should work for any types that implements your IHideable interface. Here is an example:

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"
} ]

这篇关于使用jackson序列化时有条件地跳过对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆