使用GSON避免json映射中的原始数据类型默认值

时间:2015-07-06 06:41:22

标签: java json reflection gson

public class Test {

    public int num;
    public String name;
    public String email;

    public Test(){

    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

通过使用上面的类结构我使用Gson库生成json,它工作得很好,但问题是我想避免原始数据类型默认值为json mapping.for例如

Test obj=new Test();
obj.setEmail("abc@abc.com");
obj.setName("Mike");
String json= new Gson().toJson(obj);

//输出json

{"num":0,"name":"Mike","email":"abc@abc.com"}

在输出中,json num为赋值0,它是原始数据类型int的默认值,我想避免json映射中int的默认原始数据类型。 我希望行为类似于引用类型。如果我没有为名称或电子邮件分配值,它将不会在输出json中生成。

 Test obj=new Test();
 obj.setName("Mike");
 String json= new Gson().toJson(obj);

//输出json

 {"num":0,"name":"Mike"}

如何避免输出json中的原始默认值?

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

请改用此代码,此处我将int更改为Integer,并将封装的实例变量更改为

private Integer num;
private String name;
private String email;

public Integer getNum() {
    return num;
}

public void setNum(Integer num) {
    this.num = num;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

答案 1 :(得分:0)

如果您的字段必须是原始字段,或者要从外部库中的类序列化对象,则可以使用(因此不能将其更改为包装器类)排除策略。在您指定的情况下,看起来像这样:

Gson gson = new GsonBuilder().addSerializationExclusionStrategy(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    if (f.getDeclaringClass() == Test.class && f.getName().equals("num")) {
                        return true;
                    }
                    return false;
                }
                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
})

您可以在此处检查从序列化中排除字段的其他方法: https://www.baeldung.com/gson-exclude-fields-serialization#highlighter_288459

答案 2 :(得分:0)

从Google GSON库的old release docs开始,它不支持原始数据类型的类型适配器。但是从the release document开始就可以了;因此,您可以为原始类型编写自定义类型适配器。

我一直在使用最新的Google GSON库2.8.5版。我正在为我的一个Android应用程序编写一个自定义反序列化器,其中在我的应用程序的较新API中引入了某些字段的空值,并且字段类型为数字(整数/浮点数/双精度数),并且GSON抛出异常消息“ java.lang.NumberFormatException为空字符串”。我可以使用下面的代码片段来处理它:

Test.java

import com.google.gson.annotations.SerializedName;

public class Test {
    @SerializedName("num")
    public int num;

    @SerializedName("name")
    public String name;

    @SerializedName("email")
    public String email;

    //getters and setters
}

对于示例JSON {"num": "", "name": "John Doe", "email":"john.doe@example.com"},解析失败,代码为new GsonBuilder().create().fromJson(jsonString, Test.class)。但是在这里为原始类型编写自定义类型适配器确实神奇。

IntegerDeserializer.java

public class IntegerDeserializer implements JsonDeserializer<Integer> {
    @Override
    public Integer deserialize(JsonElement json, Type typeOfSrc, JsonDeserializationContext context) throws JsonParseException {
        String value = json.getAsJsonPrimitive().getAsString();
        try {
            return Integer.parseInt(value);
        } catch (Exception ex) {
            return 0;
        }
    }
}

现在将适配器用作:

new GsonBuilder()
    .registerTypeAdapter(int.class, new IntegerDeserializer())
    .create()
    .fromJson(jsonString, Test.class)

注意:此处jsonString是保存序列化json的变量。