使用Gson从JSON数组中排除空对象

时间:2014-12-24 13:39:16

标签: java serialization gson

我正在使用Gson解析对Java对象的REST API调用。

我想过滤掉数组中的空对象,例如

{
  list: [
    {"key":"value1"},
    null,
    {"key":"value2"}
  ]
}

应该会产生包含2个项目的List<SomeObject>

你怎么能用Gson做到这一点?

3 个答案:

答案 0 :(得分:0)

答案:自定义序列化程序

您可以为List.class添加自定义序列化程序,如下所示:

package com.dominikangerer.q27637811;

import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class RemoveNullListSerializer<T> implements JsonSerializer<List<T>> {

    @Override
    public JsonElement serialize(List<T> src, Type typeOfSrc,
            JsonSerializationContext context) {

        // remove all null values
        src.removeAll(Collections.singleton(null));

        // create json Result
        JsonArray result = new JsonArray();
        for(T item : src){
            result.add(context.serialize(item));
        }

        return result;
    }

}

这将使用nullCollections.singleton(null)从列表中删除removeAll()值。

注册自定义序列化程序

现在你所要做的就是将它注册到你的Gson实例,如:

g = new GsonBuilder().registerTypeAdapter(List.class, new RemoveNullListSerializer()).create();

可下载&amp;可执行示例

你可以找到这个答案,我的github stackoverflow中的确切示例回答了repo:

Gson CustomSerializer to remove Null from List by DominikAngerer


另见

答案 1 :(得分:0)

要从列表中删除所有空值而不管它们的结构如何,首先我们需要像这样注册一个带有gson的反序列化器

/**
 * <p>
 * Deserializer that helps remove all <code>null</code> values form the <code>JsonArray</code> .
 */
public class RemoveNullListDeserializer<T> implements JsonDeserializer<List<T>>
{
    /**
     * {@inheritDoc}
     */
    @Override
    public List<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
    {
        JsonArray jsonArray = new JsonArray();
        for(final JsonElement jsonElement : json.getAsJsonArray())
        {
            if(jsonElement.isJsonNull())
            {
                continue;
            }
            jsonArray.add(jsonElement);
        }

        Gson gson = new GsonBuilder().create();
        List<?> list = gson.fromJson(jsonArray, typeOfT);
        return (List<T>) list;
    }
}

然后自定义反序列化器会像这样删除null

{{1}}

希望这有助于其他想要从json数组中删除空值的人,无论传入的json结构如何

答案 2 :(得分:0)

我的回答可能晚了,但我希望它能起作用。反序列化json字符串时,可以通过删除Java对象中的所有null元素来解决此问题。因此,首先,我们为列表

类型定义自定义 JsonDeserializer
public class RemoveNullListDeserializer<T> implements JsonDeserializer<List<T>> {
    @Override
    public List<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        //TODO
    }
}

然后,删除JsonElement中的所有空元素。在这里,我们使用递归来处理这些潜在的null元素。

    private void removeNullEleInArray(JsonElement json) {
        if (json.isJsonArray()) {
            JsonArray jsonArray = json.getAsJsonArray();
            for (int i = 0; i < jsonArray.size(); i++) {
                JsonElement ele = jsonArray.get(i);
                if (ele.isJsonNull()) {
                    jsonArray.remove(i);
                    i--;
                    continue;
                }
                removeNullEleInArray(ele);
            }
        } else if (json.isJsonObject()) {
            JsonObject jsonObject = json.getAsJsonObject();
            for (String key : jsonObject.keySet()) {
                JsonElement jsonElement = jsonObject.get(key);
                if (jsonElement.isJsonArray() || jsonElement.isJsonObject()) {
                    removeNullEleInArray(jsonElement);
                }
            }

        }
    }

值得注意的是,仅删除顶级类中的null元素是不够的。

下一步,在反序列化时转移此方法。

public class RemoveNullListDeserializer<T> implements JsonDeserializer<List<T>> {
    @Override
    public List<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        removeNullEleInArray(json)
        return Gson().fromJson(json, typeOfT)
    }
}

最后,注册用于创建Gson的适配器:

    Gson gson = new GsonBuilder()
                .registerTypeAdapter(List.class, new RemoveNullListDeserializer())
                .create();

刚过去!