仅当字段位于嵌套对象中时,Gson才会序列化空值

问题描述 投票:1回答:1

我面临的问题是,当[[仅涉及非顶级属性时,我想对空值进行ser / des,而我不知道如何实现。假设我有一个User类:

Class User { String name; int id; Address address; }
和一个地址类:

Class Address{ String street; String city; String country; }

现在,我可以在Gson实例下面使用Ser / des空值:

Gson gson = new GsonBuilder().serializeNulls().create(); Address address = new Address(null, "New York", "US"); User user = new User("Adam", 123, address); String userJson = gson.toJson(user);

输出为:

{ "name": "Adam", "id": 123, "address": { "street": null, "city": "New York", "country": "US" } }

但是,我做

NOT

想要对用户的顶级属性进行Ser / des空值处理。例如下面的用户:User user = new User("Adam", 123, null);
我希望具有以下输出,并且没有

address字段:

{ "name": "Adam", "id": 123 }
我现在正尝试使用自定义的序列化器对每个顶级属性进行硬编码,如果它们为空,则将其删除:

public class SerializerForUser implements JsonSerializer<ConfigSnapshot> { @Override public JsonElement serialize(User user, Type type, JsonSerializationContext jsc) { Gson gson = new GsonBuilder().serializeNulls().create(); JsonObject jsonObject = gson.toJsonTree(user).getAsJsonObject(); if (user.getAddress() == null) { jsonObject.remove("address"); } // if... (same with other top-level attributes) return jsonObject; } } Gson gson = new GsonBuilder().serializeNulls().registerTypeAdapter(User.class, new SerializerForUser()).create();

但是以某种方式它不起作用,例如,当地址为空时,我仍然会得到下面的输出:

{ "name": "Adam", "id": 123, "address: null }

有人可以给我一些提示,指出我在这里错了什么吗?或者,如果有人可以告诉我是否有更直接/通用的方法来实现这一目标,那将是完美的(因为我也想使用相同的gson实例来ser / des其他对象)?任何评论表示赞赏。
java gson
1个回答
0
投票
因为您正在使用

Gson gson = new GsonBuilder().serializeNulls().create();

显示空值。

要跳过显示空值,请尝试

Gson gson = new Gson();

您可以在这里测试

public static void main(String[] args) { Gson yourGson = new GsonBuilder().serializeNulls().create(); // this is how you create your Gson object, which shows null value Address address = new Address(null, "New York", "US"); User user = new User("Adam", 123, address); String userJson = yourGson.toJson(user); System.out.println(userJson); Gson newGson = new Gson(); // with this one, it doesn't show value System.out.println(newGson.toJson(user)); }

更新

我已经尝试过几次重写方法serialize,但直到我尝试#5时它都失败了>

public class UserCustomSerializer implements JsonSerializer<User> { @Override public JsonElement serialize(User src, Type typeOfSrc, JsonSerializationContext context) { JsonObject obj = new JsonObject(); if (src.name != null) { obj.addProperty("name", src.name); } obj.addProperty("id", src.id); if (src.address != null) { // try #1 //JsonObject addressJsonObj = new JsonObject(); //addressJsonObj.addProperty("street", src.address.street != null ? src.address.street : null); //addressJsonObj.addProperty("city", src.address.city != null ? src.address.city : null); //addressJsonObj.addProperty("country", src.address.country != null ? src.address.country : null); //obj.add("address", addressJsonObj); // try #2 //Gson gson = new GsonBuilder().serializeNulls().create(); //JsonElement jsonElement = gson.toJsonTree(src.address); //obj.add("address", jsonElement); // try #3 //Gson gson2 = new GsonBuilder().serializeNulls().create(); //obj.addProperty("address", gson2.toJson(src.address)); // try #4 //Gson gson = new GsonBuilder().serializeNulls().create(); //JsonObject jsonObject = gson.toJsonTree(src.address).getAsJsonObject(); //obj.add("address", jsonObject); // try #5 JsonObject addressJsonObj = new JsonObject(); addressJsonObj.addProperty("street", src.address.street != null ? src.address.street : "null"); addressJsonObj.addProperty("city", src.address.city != null ? src.address.city : "null"); addressJsonObj.addProperty("country", src.address.country != null ? src.address.country : "null"); obj.add("address", addressJsonObj); } return obj; } }

对于尝试#3,我构建了不正确的字符串。

对于尝试#1,#2和#4,我有空值问题。我搜索并找到了原因以及建议here

在JSON“对象”(又名字典)中,有两种方法来表示缺少的值:根本没有键/值对,或者具有JSON值为null的键。

因此,您可以使用.add带有适当的值,在构建JSON时,它将转换为null,或者您没有.add调用。

我的第5种方法是检查子节点是否为空,我只是从字面上添加字符串“ null”,然后在构建json字符串时将其替换]

private String parseToGson(User user){ Gson gson = new GsonBuilder().registerTypeAdapter(User.class, new UserCustomSerializer()).create(); return gson.toJson(user).replace("\"null\"", "null"); }

这里是我定义的一些测试用例

@Test public void children_attribute_is_null() throws Exception { String expected = "{\"name\":\"Adam\"," + "\"id\":123," + "\"address\":{" + "\""+ "street\":null," + "\"city\":\"New York\"," + "\"country\":\"US" + "\"}" + "}"; Address address = new Address(null, "New York", "US"); User user = new User("Adam", 123, address); assertEquals(expected, parseToGson(user)); Gson g = new Gson(); User usr = g.fromJson( parseToGson(user), User.class); assertEquals("Adam", usr.name); assertEquals(123, usr.id); assertEquals(null, usr.address.street); assertEquals("New York", usr.address.city); assertEquals("US", usr.address.country); } @Test public void parent_attribute_is_null() throws Exception { String expected = "{\"name\":\"Adam\"," + "\"id\":123" + "}"; User user = new User("Adam", 123, null); assertEquals(expected, parseToGson(user)); Gson g = new Gson(); User usr = g.fromJson( parseToGson(user), User.class); assertEquals("Adam", usr.name); assertEquals(123, usr.id); assertEquals(null, usr.address); } @Test public void parent_attribute_and_children_attribute_are_null() throws Exception { String expected = "{\"id\":123," + "\"address\":{" + "\"street\":null," + "\"city\":\"New York\"," + "\"country\":\"US" + "\"}" + "}"; Address address = new Address(null, "New York", "US"); User user = new User(null, 123, address); assertEquals(expected, parseToGson(user)); Gson g = new Gson(); User usr = g.fromJson( parseToGson(user), User.class); assertEquals(null, usr.name); assertEquals(123, usr.id); assertEquals(null, usr.address.street); assertEquals("New York", usr.address.city); assertEquals("US", usr.address.country); }

© www.soinside.com 2019 - 2024. All rights reserved.