在 Android 中使用 GSON Retrofit 从动态嵌套 json 中排除空值

Exclude null values from dynamic nested json using GSON Retrofit in Android

我正在 Android 中使用 gson 和 Retrofit 解析动态嵌套 json。我想在将其添加到列表之前排除 null/empty 个值。

我尝试了以下方法,但 none 似乎有效:

 // retMap.values().removeIf(Objects::isNull);
 //  Collection<POJOContent> values = retMap.values();
//  while (values.remove(null)) {}

//list.removeAll(Arrays.asList(""));

CustomDeserialiser.java

public class CustomDeserializer implements JsonDeserializer<MyContentWrapper> {
    private final String abc_key = "abc";

    @Override
    public MyContentWrapper deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {


        MyContentWrapper abc = new MyContentWrapper();
        JsonObject object = json.getAsJsonObject().getAsJsonObject(abc_key);
        List<POJOContent> list = new ArrayList<POJOContent>();
        System.out.println("New Data: "+object);

        for (Map.Entry<String, JsonElement> set : object.entrySet()) {
            System.out.println("LIST " + set);

            JsonObject nextObject = object.getAsJsonObject().getAsJsonObject(set.getKey());


           Map<String, POJOContent> retMap = new Gson().fromJson(nextObject, new TypeToken<LinkedHashMap<String, POJOContent>>() {
            }.getType());

            // retMap.values().removeIf(Objects::isNull);
              //  Collection<POJOContent> values = retMap.values();
              //  while (values.remove(null)) {}

                         list.addAll(retMap.values());
                //list.removeAll(Arrays.asList(""));
        
          

        }
        abc.abc = list;
        return abc;
    }

POJOContent.java

        
public class POJOContent {

    @SerializedName("ab")
    public String content;

    @SerializedName("id")
    public String id;

    @SerializedName("key")
    public String key;

    @Override
    public String toString() {
        return content;
    }

    //getters and setters

}

MyContentWrapper.java

public class MyContentWrapper {

    public List<POJOContent> abc;
}

JSON:

{
    "abc": {
        "1": {
            "1": {
                "ab": "some content",
                "id": "240",
                "key": "value"
            },
            "2": {
                "ab": "some content",
                "id": "240",
                "key": "value"
            },
            "3": {
                "ab": "some content",
                "id": "240",
                "key": "value"
            }
        },
        "2": {
            "1": {
                "ab": "some content",
                "id": "241",
                "key": "value"
            },
            "2": {
                "ab": "some content",
                "id": "241",
                "key": "value"
            },
            "3": {
                "ab": "some content",
                "id": "241",
                "key": "value"
            }
        },
        "3": {
            "1": {
                "ab": "",
                "id": "252",
                "key": "value"
            },
            "2": {
                "ab": "some content",
                "id": "252",
                "key": "value"
            },
            "3": {
                "ab": "",
                "id": "252",
                "key": "value"
            }
        }
    }
}

基本上,我想跳过“ab”值为空的对象,而不是将它们添加到列表中(如果“ab”值为空,则其他键无关紧要)。澄清一下,如果父对象有任何带有“ab”键空值的子对象,则应排除该子对象。如果父对象的所有子对象的“ab”键为空值,则应排除父对象。

我错过了什么吗?非常感谢您的帮助。

编辑:: 预期 JSON:

{
    "abc": {
        "1": {
            "1": {
                "ab": "some content",
                "id": "240",
                "key": "value"
            },
            "2": {
                "ab": "some content",
                "id": "240",
                "key": "value"
            },
            "3": {
                "ab": "some content",
                "id": "240",
                "key": "value"
            }
        },
        "2": {
            "1": {
                "ab": "some content",
                "id": "241",
                "key": "value"
            },
            "2": {
                "ab": "some content",
                "id": "241",
                "key": "value"
            },
            "3": {
                "ab": "some content",
                "id": "241",
                "key": "value"
            }
        },
        "3": {
            "2": {
                "ab": "some content",
                "id": "252",
                "key": "value"
            }
        }
    }
}

更新 2:

这是我将列表更改为地图后得到的响应:

        Callback<MyContentWrapper> myCallback = new Callback<MyContentWrapper>() {
        @Override
        public void onResponse(Call<MyContentWrapper> call, Response<MyContentWrapper> response) {
            if (response.isSuccessful()) {
                Log.d("Callback", " Message: " + response.raw());
                Log.d("Callback", " Message: " + response.body().abc.values());
                still showing empty brackets here --->  
//Log.d =     Message: [{1=1. some content, 1=2. some content, 1=3. some content}, {}]
            } else {
                Log.d("Callback", "Code: " + response.code() + " Message: " + response.message());
            }
        }
        @Override
        public void onFailure(Call<MyContentWrapper> call, Throwable t) {
            t.printStackTrace();
        }
    };

仅供参考,这是对上述回调的 JSON 响应:


{
    "abc": {
        "1": {
            "1": {
                "ab": "some content",
                "id": "240",
                "key": "value"
            },
            "2": {
        "ab": "some content",
        "id": "240",
        "key": "value"
            },
      "3": {
        "ab": "some content",
        "id": "240",
        "key": "value"
            }
        },
        "2": {
            "1": {
          "ab": "",
          "id": "241",
          "key": "value"
            },
            "2": {
          "ab": "",
          "id": "241",
          "key": "value"
            },
      "3": {
          "ab": "",
          "id": "241",
          "key": "value"
      }
        }
    }
}

首先你的MyContentWrapper是错误的。根据您的 JSON,它不是 List。它应该是地图的地图,类似于:

public class MyContentWrapper {
    public Map<Integer, Map<Integer, POJOContent>> abc;
}

现在,您可以为这种结构编写一些复杂的反序列化器,但还有另一种方法可以做到这一点。也就是说,如果你声明 helper Map 像:

@SuppressWarnings("serial")
public class MyMap extends HashMap<Integer, POJOContent> {
    @Override
    public POJOContent put(Integer key, POJOContent value) {
        if(null==value.getContent() || value.getContent().isBlank()) {
            return null;
        }
        // Added only if content = "ab" is not blank.
        return super.put(key, value);
    }
}

然后调谐 MyContentWrapper:

public class MyContentWrapper {
    public Map<Integer, MyMap> abc;
}

那就只有:

MyContentWrapper mcw = new Gson().fromJson(JSON, MyContentWrapper.class);