Jackson: Serialize null object as empty

岁酱吖の 提交于 2019-12-22 11:28:27

问题


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.

for instance I have following models:

class First {

    private firstField;
    private secondField;
    etc...
}

class Second {

    private firstField;
    private secondField;
    etc...
}

class General {

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

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
}

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

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

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?

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

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.


回答1:


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.

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.



来源:https://stackoverflow.com/questions/45565848/jackson-serialize-null-object-as-empty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!