oblac / jodd

Jodd! Lightweight. Java. Zero dependencies. Use what you like.
https://jodd.org
BSD 2-Clause "Simplified" License
4.06k stars 724 forks source link

How to use JsonSerializer serialize bean to json string that exclude null values? #223

Closed baishui2004 closed 9 years ago

baishui2004 commented 9 years ago

jodd 3.6.6

zqq90 commented 9 years ago

Step 1: MyMapJsonSerializer & MyObjectJsonSerializer

class MyMapJsonSerializer extends ValueJsonSerializer<Map<?, ?>> {

    @Override
    public void serializeValue(final JsonContext jsonContext, Map<?, ?> map) {
        jsonContext.writeOpenObject();
        boolean notfirst = false;
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            final Object value = entry.getValue();
            if (value == null) {
                continue;
            }
            final Object key = entry.getKey();
            jsonContext.pushName(key != null ? key.toString() : null, notfirst);
            jsonContext.serialize(value);
            if (!notfirst && jsonContext.isNamePopped()) {
                notfirst = true;
            }
        }
        jsonContext.writeCloseObject();
    }
}
class MyObjectJsonSerializer extends ObjectJsonSerializer{
    protected void onSerializableProperty(String propertyName, Class propertyType, Object value) {
            if (value == null) {
                return;
            }
        super.onSerializableProperty(propertyName, propertyType, value);
    }
}

Step 2: replace default Serializer for Map & Common bean

JoddJson.defaultSerializers.register(Map.class, new MyMapJsonSerializer());
JoddJson.defaultSerializers.register(Object.class, new MyObjectJsonSerializer());

Or

new JsonSerializer()
                //.deep(true)
                .use(Map.class, new MyMapJsonSerializer())
                .use(Object.class, new MyObjectJsonSerializer())
                .serialize(src);

Hope it match your wanted

baishui2004 commented 9 years ago

Tank you!

I try this on jodd 3.6.6, then compile error.

class MyObjectJsonSerializer extends ObjectJsonSerializer{
    protected void onSerializableProperty(String propertyName, Class propertyType, Object value) {
            if (value == null) {
                return;
            }
        super.onSerializableProperty(propertyName, propertyType, value);
    }
}

then i use that below,

public class MyBeanSerializer extends ObjectJsonSerializer {
    public void serializeValue(JsonContext jsonContext, Object value) {
        if (value == null) {
            return;
        }
        super.serializeValue(jsonContext, value);
    }
}
……
new JsonSerializer().deep(true).use(Object.class, new MyBeanSerializer()).serialize(object);

and it's not work.

zqq90 commented 9 years ago

@baishui2004 sorry for my misstake

public class MyObjectJsonSerializer extends ValueJsonSerializer<Object> {

    public void serializeValue(final JsonContext jsonContext, Object value) {
        jsonContext.writeOpenObject();

        MyBeanSerializer beanVisitor = new MyBeanSerializer(jsonContext, value);
        beanVisitor.serialize();

        jsonContext.writeCloseObject();
    }
}

public class MyBeanSerializer extends BeanSerializer {

    public MyBeanSerializer(JsonContext jsonContext, Object bean) {
        super(jsonContext, bean);
    }

    @Override
    protected void onSerializableProperty(String propertyName, Class propertyType, Object value) {
        if (value == null) {
            return;
        }
        super.onSerializableProperty(propertyName, propertyType, value);
    }
}

@igorspasic :smile: consider this feature

igr commented 9 years ago

Thanx @zqq90 for prompt answer! Let me add the excludeNulls() to the serializer!

igr commented 9 years ago

Also, another option is to use eg BeanCopy to copy bean to a Map and use excludeNull option. Then to serialize the Map.

This is slightly slower, since we are copying to the Map first, but can be an option, too :)

igr commented 9 years ago

Sorry @baishui2004 for long response, it's a bit crazy here these days!

baishui2004 commented 9 years ago

Never mind, don't overdo it, Thank you all @igorspasic @zqq90