EC84B4
EC84B4

Reputation: 7696

how to config gson to exclude 0 integer values

I've a Java class with lot of integer fields and when I want to serialize them to json string due to some of them could have no value, hence after serializing all integers get zero as values ! I want to config gson not to serialize them if they do not have any values.

for example I have this class :

class Example {
   String title = "something";
   int id = 22;
   int userId;
} 

by default gson gives me this result :

{
   "title" : "something",
   "id" : 22,
   "userId" : 0
}

but i don't want the userId to be serialized when its value is 0. so the json should be:

{
   "title" : "something",
   "id" : 22
}

for objects by default gson doesn't serialize null objects is there a way to config gson not to serialize 0 numbers

Upvotes: 16

Views: 9482

Answers (4)

Nitin Gawande
Nitin Gawande

Reputation: 373

We have to just use class Integer (Integer javadoc).

class Example {
   String title = "something";
   Integer id = 22;
   Integer userId;
}

Upvotes: 34

Marco Curvello
Marco Curvello

Reputation: 33

I want to config gson not to serialize them if they do not have any values.

This sentence leads me to believe you misunderstand how variables and values work in Java. Note that all variables in Java have a value even if you don't explicitly assign one to them. If you declare an int and do not assign it a value, a default value of 0 will be assigned for you. So this:

int userId;

is equivalent to this:

int userId = 0;

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

Although Nitin Gawande's answer is not correct per se, I would still recommend it since I assume that's probably what you want. A null value for an Integer is a more reliable representation of a value that was never assigned than a zero value for an int (usually). And it allows you to make use of GSON's handy "don't serialize nulls" feature.

Upvotes: 0

Mirko Ploch
Mirko Ploch

Reputation: 101

Create this JSON type adapter. It can be used where ever you want to ignore writing zero values. It can also be adapted to Long, Double and other numeric types. You can also change it to ignore writing a value other than zero.

Yes I know Autoboxing and Unboxing is implicitly used but you can't specify a primitive type for the generic type.

public class IntIgnoreZeroAdapter extends TypeAdapter<Integer> {
    private static Integer INT_ZERO = Integer.valueOf(0);

    @Override
    public Integer read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return 0;
        }

        return in.nextInt();
    }

    @Override
    public void write(JsonWriter out, Integer data) throws IOException {
        if (data == null || data.equals(INT_ZERO)) {
            out.nullValue();
            return;
        }

        out.value(data.intValue());
    }
}

Change your class to specify the IntIgnoreZeroAdapter for the int members.

class Example {
   String title = "something";

   @JsonAdapter(IntIgnoreZeroAdapter.class)
   int id = 22;

   @JsonAdapter(IntIgnoreZeroAdapter.class)
   int userId;
} 

Upvotes: 9

Devrim
Devrim

Reputation: 15533

You can write a custom TypeAdapter.

public class ExampleTypeAdapter extends TypeAdapter<Example> {

    @Override
    public Example read(com.google.gson.stream.JsonReader in)
            throws IOException {
        final Example example = new Example();

        in.beginObject();
        while (in.hasNext()) {
            String name = in.nextName();
            if ("title".equals(name)) {
                example.title = in.nextString();
            } else if ("id".equals(name)) {
                example.id = in.nextInt();
            } else if ("userId".equals(name)) {
                example.userId = in.nextInt();
            }
        }
        in.endObject();

        return example;
    }

    @Override
    public void write(com.google.gson.stream.JsonWriter out, Example example)
            throws IOException {
        out.beginObject();
        out.name("title").value(example.title);

        if(example.id != 0) {
            out.name("id").value(example.id);
        }

        if(example.userId != 0) {
            out.name("userId").value(example.userId);
        }

        out.endObject();
    }
}

Try it with code below:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Example.class, new ExampleTypeAdapter());
gsonBuilder.setPrettyPrinting();

Gson gson = gsonBuilder.create();

Example example = new Example();
example.title = "mytitle";
example.id = 1234;
example.userId = 0;

final String json = gson.toJson(example);
System.out.println(json);

Output will be:

 {
   "title": "my title",
   "id": 1234
 }

Note: Important part is at write method of our custom TypeAdapter.

Upvotes: 7

Related Questions