乔德:不序列化空对象

时间:2018-07-17 00:35:07

标签: java json serialization jodd

当前,我们正在使用JODD lib进行JSON序列化。但是它总是序列化空对象。我希望将对象非空对象序列化为Json字符串。我们该怎么做?

Expecting:
{payload={app={id=xxx, version=0, hash=asdf, riskData={}}}}
--->
{"payload":{"app":{"id":"xxx","version":0,"hash":"asdf"}}} // not to show riskdata.

我们在Jodd 3.7.1中使用JsonSerializer。 有帮助吗?

我们使用Jodd的情况是我们试图序列化嵌入式日志映射对象。

/* inside this Map, there could be several embedded objects. */
/* ie. {payload={app={id=xxx, version=0, hash=asdf, riskData={}}}} */
Map<String, Object> log; 

由于此Map是从JSON字符串反序列化的,因此我们不能使用任何注释来标记空字段。 我们想使用JsonSerializer将此Map对象序列化为JSON字符串,并排除任何包含空值的字段,例如空map(riskData)或空列表。

昨天我深入研究了代码。并找到了一种可能的解决方案,那就是扩展默认的JsonSerializers,例如:

public class NonEmptyMapSerializer extends MapJsonSerializer {
    @Override
    public void serializeValue(JsonContext jsonContext, Map<?, ?> map) {
        // If Map is empty. Skip it.
        if (map.isEmpty()) return;
        super.serializeValue(jsonContext, map);
    }
}
/*-----When initiating a JsonSerializer-----*/
logAllSerializer = new JsonSerializer().withSerializer(Map.class, new NonEmptyMapSerializer());

与其他类型相同。

此解决方案正确吗?会引起任何意想不到的行为吗?还是可以提供其他更好的解决方案? 我可以找到一个选项:.excludeNulls(true),但仅排除NULL字段。是否有“ excludeEmpty”的隐藏选项?

非常感谢!

2 个答案:

答案 0 :(得分:1)

好吧,因为到目前为止没有人响应,所以我将针对我自己的问题发布我唯一的解决方案。

对于每种类型的对象(String / Map / Integer / Iterable ...),Jodd定义了自己的默认序列化器。例如,对于Map.class,默认的序列化程序如下所示:

/**
 * Map serializer.
 */
public class MapJsonSerializer extends KeyValueJsonSerializer<Map<?, ?>> {

    @Override
    public void serializeValue(JsonContext jsonContext, Map<?, ?> map) {
        jsonContext.writeOpenObject(); // In here, it outputs "map-name":{

        int count = 0;

        Path currentPath = jsonContext.getPath();

        for (Map.Entry<?, ?> entry : map.entrySet()) {
            Object key = entry.getKey();
            Object value = entry.getValue();

            count = serializeKeyValue(jsonContext, currentPath, key, value, count); // in here it serialize each key/value pair recursively.
        }

        jsonContext.writeCloseObject(); // in here, it outputs the closing parenthe like '}' to close this map.
    }
}

所以,我的解决方案是创建自己的Map序列化程序,该序列化程序首先检查映射是否为空。如果不为空,请使用默认的序列化程序对其进行序列化。如果为空,则返回而不显示任何内容。

public class NonEmptyMapSerializer extends MapJsonSerializer {
    @Override
    public void serializeValue(JsonContext jsonContext, Map<?, ?> map) {
        // If Map is empty. Skip it.
        if (map == null) return;
        if (map.isEmpty()) return;
        super.serializeValue(jsonContext, map);
    }
}

希望它会有所帮助!如果遇到类似问题,这可能是一种可能的解决方案。

答案 1 :(得分:1)

对于null值,已经有一个excludeNulls标志:

String json = new JsonSerializer().excludeNulls(true).serialize(map);

此值将忽略所有 null个值。

新标志(刚刚提交)用于空值:excludeEmpty()。可以按预期使用它:

json = new JsonSerializer().excludeNulls(true).excludeEmpty(true).serialize(map);

最后,您可以使用新的回调来进行更多控制,例如:

json = new JsonSerializer().excludeNulls(true).onValue(value -> {
        if (value instanceof Map) {
            if (((Map)value).isEmpty()) {
                return new EmptyJsonSerializer();
            }
        }
        return null;
    }).serialize(map);