如何配置Gson以排除0整数值

15

我有一个 Java 类,其中有许多整数字段。当我想将它们序列化为 JSON 字符串时,由于其中一些可能没有值,因此在序列化后,所有整数都会获得零作为值!我希望配置 Gson 不序列化它们,如果它们没有任何值。

例如,我有这个类:

class Example {
   String title = "something";
   int id = 22;
   int userId;
} 
默认情况下,Gson 给出了这个结果:

by default gson gives me this result :

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

但是当 userId 的值为 0 时,我不希望对其进行序列化。因此,JSON 应该如下所示:

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

对于对象,默认情况下,Gson不会序列化空对象。有没有一种方法可以配置Gson不将0数字序列化?


4个回答

33

我们只需要使用类 IntegerInteger javadoc)即可。

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

2
这并不完全符合问题的要求。在这个例子中,您已经将0换成了null,并利用了GSON的“不序列化null”功能。 - CarlG

9
创建这个JSON类型适配器。它可以在任何你想要忽略写入零值的场景中使用。它也可以适应长整型、双精度和其他数值类型。你还可以将它改为忽略写入非零值。是的,我知道自动装箱和拆箱是隐式使用的,但是你无法为泛型类型指定基本类型。
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());
    }
}

将你的类更改为指定IntIgnoreZeroAdapter用于int成员。

class Example {
   String title = "something";

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

   @JsonAdapter(IntIgnoreZeroAdapter.class)
   int userId;
} 

如果想要忽略一个值的话怎么办? - Bhavesh Vadalia
比编写整个对象类的TypeAdapters更加灵活和易于实现。 - Brent Easton
如果您不想使用注释,可以将类型适配器注册到GsonBuilder中:builder.registerTypeAdapter(Integer.class, new IntAdapter()); - rupweb

7
您可以编写自定义的。
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();
    }
}

请尝试以下代码:
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);

输出结果如下:
 {
   "title": "my title",
   "id": 1234
 }

注意:重要的部分在我们自定义的TypeAdapterwrite方法中。


很棒的回答!谢谢你! - Peter Zhao

0
我想配置gson,如果它们没有任何值,则不对它们进行序列化。
这句话让我相信您误解了Java中变量和值的工作方式。请注意,即使您没有明确为Java中的所有变量分配值,它们也都有一个值。如果您声明一个int并未为其分配值,则会为您分配默认值0。因此,以下代码:
int userId;

等同于:

int userId = 0;

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

尽管Nitin Gawande的答案本身并不正确,但我仍然建议使用它,因为我认为那可能是你想要的。对于未分配值的更可靠表示,Integernull值比int的零值(通常)更可靠。它还允许您利用GSON的方便的“不序列化nulls”功能。


1
这是很久以前的事了,我已经记不清我最终使用了什么,但其要点是我不想序列化值为0的整数。 - EC84B4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接