【问题标题】:Exclude null values from dynamic nested json using GSON Retrofit in Android在 Android 中使用 GSON Retrofit 从动态嵌套 json 中排除空值
【发布时间】:2020-11-11 07:09:21
【问题描述】:

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

我尝试了以下方法,但似乎都不起作用:

 // 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:

这是我将 List 更改为 Maps 后得到的响应:

        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"
      }
        }
    }
}

【问题讨论】:

  • 您能否在排除这些值后提供预期的 JSON?
  • @because_im_batman,我已经用预期的 JSON 更新了代码。抱歉,我在描述中犯了一个错误,需要澄清 - 如果父对象有 1 个子对象,其中“ab”键为空,则应排除子对象。如果父对象的所有子对象的“ab”键为空值,则应排除父对象。我希望你能理解我想要表达的意思。

标签: java android json gson retrofit2


【解决方案1】:

首先你的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);

【讨论】:

  • 感谢您的帮助。我进行了更改,但我仍然得到空括号。 Message: [{1=1. some content, 1=2. some content, 1=3. some content}, {}] 请看我更新的代码。
  • 没关系,我想通了。非常感谢您的帮助。
  • 嗨,你能帮我解决这个问题吗:stackoverflow.com/questions/63786149/… ?真的很感激。
猜你喜欢
  • 2019-09-25
  • 1970-01-01
  • 2021-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-07
相关资源
最近更新 更多