2

I'm using Gson to parse my REST API calls to Java objects.

I want to filter out null objects in an array, e.g.

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

should result in a List<SomeObject> with 2 items.

How can you do this with Gson?

2
  • Added an answer which may cover your needs :) let me know if you need additional support. Commented Apr 19, 2015 at 19:23
  • @Quentin did you get answer of this question i also have same problem... Commented Nov 17, 2016 at 10:35

3 Answers 3

2

Answer: The Custom Serializer

You can add a custom serializer for List.class which would look like:

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;
    }

}

This will remove the null values from the list using Collections.singleton(null) and removeAll().

Register your Custom Serializer

Now all you have to do is register it to your Gson instance like:

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

Downloadable & executable Example

You can find this answer and the exact example in my github stackoverflow answers repo:

Gson CustomSerializer to remove Null from List by DominikAngerer


See also

Sign up to request clarification or add additional context in comments.

7 Comments

is this also possible in the other direction? deserialization?
Sure - you can write your own deserializer for that. @Override public List<T> deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException { ... }
@DominikAngerer During de-serialization if the structure of the json is not know how would you remove all the null's from the given json element?
@striker good question - I will think about a solution and come back to this :)
@DominikAngerer I found a solution for this, the trick would be to register a derserializer for the type List and have a deserializer to remove all the JSON Null, I posted in the answers section, so it may help others as well
|
1

To remove all the null values from a list regardless of their structure, first we need to register a de-serializer with the gson like this

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

Then the custom de-serializer would remove the null like this

/**
 * <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;
    }
}

Hope this help others, who want to remove null values from a json array, regardless of the incoming json structure

Comments

0

My answer maybe late but I expect it works. This question can be solved by removing all the null elements in the Java object when deserialize the json string. So first, we define the custom JsonDeserializer for type List

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

And then, remove all null elements in the JsonElement. Here we use recursive to handle these potential null elements.

    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);
                }
            }

        }
    }

It's worth noting that only remove the null elements in top class is not enough.

And next step, transfer this method when deserialize.

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)
    }
}

Finally, register the adapter for creating your Gson:

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

Just Over!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.