杰克逊:将null对象序列化为空 [英] Jackson: Serialize null object as empty

查看:117
本文介绍了杰克逊:将null对象序列化为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有大量的json文档和映射到json的适当的jaskson模型。在某些情况下,无法使用所有对象构建所需的json文档,因为某些数据不存在。

I have huge json document and appropriate jaskson models that are mapped to that json. In some cases it is not possible to build the required json document with all object because some data does not exist.

例如我有以下模型:

class First {

    private firstField;
    private secondField;
    etc...
}

class Second {

    private firstField;
    private secondField;
    etc...
}

class General {

    private First first;
    private Second second;
    etc...
}

并且有可能只填充First实例:

And there is possibility to populate only First instance:

在通常的情况下,它将被序列化如下:

In usual cases it will be serialized something like this:

{
   "first":{
      "firstField":"some_value",
      "secondField":"some_value"
   },
   "second":null
}

但我的目标是将General类序列化为:

But my goal is to serialize General class something like this:

{  
   "first":{  
      "firstField":"some_value",
      "secondField":"some_value"
   },
   "second":{  
      "firstField":"null",
      "secondField":"null"
   }
}

可以通过General类中的以下更改来实现此目的,以便使用默认值初始化其成员默认情况下构造函数:

It is possible to achieve this with following changes in General class in order to initialize their members using default constructors by default:

class General {

        private First first = new First();
        private Second second = new Second()
        etc...
    }

但是这种方法会对现有模型造成太多变化,我不确定它是最好的方法。是否有可能创建一些自定义的自定义序列化程序?

But this approach will cause too many changes around existing models and I am not sure that it is the best one approach. Is it possible to create some custom serializer that will do this by itself?

根据 https://stackoverflow.com/users编辑/ 1898563 / michael 建议:

Edited according to https://stackoverflow.com/users/1898563/michael suggestion:

所以,主要的想法是创建能够检查实例是否为空的序列化程序,如果它是null它应该能够使用默认构造函数创建新实例,注意:此序列化程序不应该基于特定的第二个类,它应该使用除了简单类型之外将被序列化的任何对象。

So, the main idea is to create serializer that would be able to check whether instance is null and if it is null it should be able to create new instance using default constructor, note: this serializer should not be based on specific Second class, it should work with any object that is going to be serialized except simple types.

推荐答案

是的,可以创建一个使用的自定义序列化程序反思这样做。你可以通过扩展 StdSerializer 。您的实现可能如下所示:

Yes, its possible to create a custom serializer which uses reflection to do this. You can do this by extending StdSerializer. Your implementation might look something like this:

public class NullSerializer<T> extends StdSerializer<T> {

    public NullSerializer() {
        this(null);
    }

    public NullSerializer(Class<T> t) {
        super(t);
    }

    @Override
    public void serialize(T item, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonProcessingException,
            IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException)
    {

        jgen.writeStartObject();

        // For all fields of the class you're serializing
        for (final Field field : item.getClass().getDeclaredFields())
        {
            field.setAccessible(true);

            Object value = field.get(item);

            // if the value is null, create a new instance
            if (value == null)
            {  
                value = field.getType().getConstructor().newInstance();
            }

            // write it
            jgen.writeObject(value);
        }

        jgen.writeEndObject();
    }
}

这取决于每个都有一个公共默认构造函数的领域。您可能想要捕获一些异常而不是像我一样将它们声明为抛出签名。

This relies on there being a public default constructor for each of the fields. You may want to catch some of the exceptions rather than declare them as thrown in the signature as I've done.

您需要使用ObjectMapper注册此序列化程序。 这篇文章解释了如何做到这一点。

You need to register this serializer with the ObjectMapper. This article explains how to do that.

我不认为这是一个特别优雅的解决方案,但它应该满足您的要求。我会首先避免使用可以为空的字段,但也许在你的情况下这是不可能的。

I don't think this is a particularly elegant solution, but it should fulfill your requirements. I would avoid having nullable fields in the first place, but maybe that's not possible in your case.

这篇关于杰克逊:将null对象序列化为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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