使用Gson从JSON中移除空集合

9njqaruj  于 2022-12-04  发布在  其他
关注(0)|答案(3)|浏览(219)

我要使用gson移除具有空集合或null值的属性。

Aiperiodo periodo = periodoService();
//periodo comes from a service method with a lot of values
Gson gson = new Gson();
String json = gson.toJson(periodo);

我打印了json并得到了这个:

{"idPeriodo":121,"codigo":"2014II",
"activo":false,"tipoPeriodo":1,
"fechaInicioPreMatricula":"may 1, 2014",
"fechaFinPreMatricula":"jul 1, 2014",
"fechaInicioMatricula":"jul 15, 2014",
"fechaFinMatricula":"ago 3, 2014",
"fechaInicioClase":"ago 9, 2014",
"fechaFinClase":"dic 14, 2014",
"fechaActa":"ene 15, 2015",
"fechaUltModificacion":"May 28, 2014 12:28:26 PM",
"usuarioModificacion":1,"aiAvisos":[],
"aiAlumnoCarreraConvalidacionCursos":[],
"aiAlumnoMatriculas":[],"aiMallaCurriculars":[],
"aiAlumnoCarreraEstados":[],"aiAdmisionGrupos":[],
"aiMatriculaCronogramaCabeceras":[],
"aiAlumnoCarreraConvalidacions":[],
"aiHorarioHorases":[],"aiAsistencias":[],
"aiAlumnoPreMatriculas":[],
"aiAlumnoMatriculaCursoNotaDetalles":[],
"aiOfertaAcademicas":[],"aiTarifarios":[]}

例如,对于那个json,我不想拥有集合aiAvisos,有一种方法可以从json中删除它。我正在处理很多集合,实际上这里我展示了一个,我真的需要从json中删除这些集合。
我需要这样的东西:

{"idPeriodo":121,"codigo":"2014II",
"activo":false,"tipoPeriodo":1,
"fechaInicioPreMatricula":"may 1, 2014",
"fechaFinPreMatricula":"jul 1, 2014",
"fechaInicioMatricula":"jul 15, 2014",
"fechaFinMatricula":"ago 3, 2014",
"fechaInicioClase":"ago 9, 2014",
"fechaFinClase":"dic 14, 2014",
"fechaActa":"ene 15, 2015",
"fechaUltModificacion":"May 28, 2014 12:28:26 PM",
"usuarioModificacion":1}

我试着将集合设置为null,我检查了文档,那里也没有方法...
请提出建议。
谢谢你读了这篇文章!

yb3bgrhw

yb3bgrhw1#

步骤如下:

  • 使用Gson#fromJson()将JSON字符串转换为Map<String,Object>
  • 迭代Map并从Map中删除null或空ArrayListMap的条目。
  • 使用Gson#toJson()从最终Map中返回JSON字符串。
    **注意:**使用GsonBuilder#setPrettyPrinting()配置Gson以输出适合页面的Json,从而实现漂亮的打印效果。

样本代码:

import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
...  
 
Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> data = new Gson().fromJson(jsonString, type);

for (Iterator<Map.Entry<String, Object>> it = data.entrySet().iterator(); it.hasNext();) {
    Map.Entry<String, Object> entry = it.next();
    if (entry.getValue() == null) {
        it.remove();
    } else if (entry.getValue().getClass().equals(ArrayList.class)) {
        if (((ArrayList<?>) entry.getValue()).size() == 0) {
            it.remove();
        }
    } else if (entry.getValue() instanceof Map){ //removes empty json objects {}
        Map<?, ?> m = (Map<?, ?>)entry.getValue();
        if(m.isEmpty()) {
           it.remove();
        }
    }
}

String json = new GsonBuilder().setPrettyPrinting().create().toJson(data);
System.out.println(json);

输出;

{
    "idPeriodo": 121.0,
    "codigo": "2014II",
    "activo": false,
    "tipoPeriodo": 1.0,
    "fechaInicioPreMatricula": "may 1, 2014",
    "fechaFinPreMatricula": "jul 1, 2014",
    "fechaInicioMatricula": "jul 15, 2014",
    "fechaFinMatricula": "ago 3, 2014",
    "fechaInicioClase": "ago 9, 2014",
    "fechaFinClase": "dic 14, 2014",
    "fechaActa": "ene 15, 2015",
    "fechaUltModificacion": "May 28, 2014 12:28:26 PM",
    "usuarioModificacion": 1.0
  }
pieyvz9o

pieyvz9o2#

我在Kotlin中尝试了一个@Braj的解决方案,想法是将JSON转换为Map,删除null和空数组,然后将Map转换回JSON字符串。
但它有几个缺点。
1.它只能处理没有嵌套的简单POJO(没有内部类、类列表)。
1.它将数字转换为双精度数(因为Object不能被识别为int)。
1.从String转换为String会浪费时间。
或者,您可以尝试使用Moshi而不是Gson,请参阅Broken server response handling with Moshi
几天后,我克服了复杂JSON的第一个问题。

import android.support.annotation.NonNull;

import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

public class GsonConverter {

    private Type type;
    private Gson gson;

    public GsonConverter() {
        type = new TypeToken<Map<String, Object>>() {
        }.getType();
        gson = new Gson();
    }

    /**
     * Remove empty arrays from JSON.
     */
    public String cleanJson(String jsonString) {
        Map<String, Object> data = gson.fromJson(jsonString, type);
        if (data == null)
            return "";

        Iterator<Map.Entry<String, Object>> it = data.entrySet().iterator();
        traverse(it);

        return gson.toJson(data);
    }

    private void traverse(@NonNull Iterator<Map.Entry<String, Object>> iterator) {
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            Object value = entry.getValue();
            if (value == null) {
                iterator.remove();
                continue;
            }

            Class<?> aClass = value.getClass();
            if (aClass.equals(ArrayList.class)) {
                if (((ArrayList) value).isEmpty()) {
                    iterator.remove();
                    continue;
                }
            }

            // Recoursively pass all tags for the next level.
            if (aClass.equals(ArrayList.class)) {
                Object firstItem = ((ArrayList) value).get(0);
                Class<?> firstItemClass = firstItem.getClass();

                // Check that we have an array of non-strings (maps).
                if (firstItemClass.equals(Map.class)) {
                    // Array of keys and values.
                    @SuppressWarnings("unchecked")
                    ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
                    for (Map<String, Object> item : items) {
                        traverse(item.entrySet().iterator());
                    }
                } else if (firstItemClass.equals(LinkedTreeMap.class)) {
                    // Array of complex objects.
                    @SuppressWarnings("unchecked")
                    ArrayList<LinkedTreeMap<String, Object>> items = (ArrayList<LinkedTreeMap<String, Object>>) value;
                    for (LinkedTreeMap<String, Object> item : items) {
                        traverse(item.entrySet().iterator());
                    }
                }
            } else if (aClass.equals(LinkedTreeMap.class)) {
                @SuppressWarnings("unchecked")
                LinkedTreeMap<String, Object> value2 = (LinkedTreeMap<String, Object>) value;
                traverse(value2.entrySet().iterator());
            }
        }
    }
}

用法:

YourJsonObject yourJsonObject = new Gson().fromJson(new GsonConverter().cleanJson(json), YourJsonObject.class);

对于那些想要使用@Braj解决方案的人,这里有一个Kotlin中的代码。

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import java.lang.reflect.Type

class GsonConverter {

    private val type: Type = object : TypeToken<Map<String, Any?>>() {}.type
    private val gson = Gson()
    private val gsonBuilder: GsonBuilder = GsonBuilder()//.setLongSerializationPolicy(LongSerializationPolicy.STRING)

    fun convert(jsonString: String): String {
        val data: Map<String, Any?> = gson.fromJson(jsonString, type)

        val obj = data.filter { it.value != null && ((it.value as? ArrayList<*>)?.size != 0) }

        val json = gsonBuilder/*.setPrettyPrinting()*/.create().toJson(obj)
        println(json)

        return json
    }
}
0pizxfdo

0pizxfdo3#

我有一段代码可以处理不同结构的数组或对象,并递归地删除“空集合或空值”。它可以处理String而不是直接处理Gson。如果不是很关键,它可以帮助你。
您的代码将是:

Aiperiodo periodo = periodoService();
//periodo comes from a service method with a lot of values
Gson gson = new Gson();
String json = gson.toJson(periodo);
json = removeNullAndEmptyElementsFromJson(json);

...

import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import java.util.Iterator;
import java.util.Map;

public class IoJ {

public static void main(String[] args) {
    String j = "{\"query\":\"\",\"name\":null,\"result\":{\"searchResult\":[{\"id\":null,\"phone\":\"123456\",\"familyAdditionalDetails\":[],\"probability\":0.0,\"lastUpdated\":\"2019-05-18T12:03:34Z\",\"empty\":false,\"gender\":\"F\"}]},\"time\":1558181014060}";

    // {"query":"","name":null,"result":{"searchResult":[{"id":null,"phone":"123456","familyAdditionalDetails":[],"probability":0.0,"lastUpdated":"2019-05-18T12:03:34Z","empty":false,"gender":"F"}]},"time":1558181014060}
    System.out.println(j);
    // (additional spaces for easier check)
    // {"query":"",            "result":{"searchResult":[{          "phone":"123456",                             "probability":0.0,"lastUpdated":"2019-05-18T12:03:34Z","empty":false,"gender":"F"}]},"time":1558181014060}
    System.out.println(removeNullAndEmptyElementsFromJson(j));
}

public static String removeNullAndEmptyElementsFromJson(String jsonString) {
    if (jsonString == null) {
        return jsonString;
    }
    try {
        JsonParser parser = new JsonParser();
        JsonElement element = parser.parse(jsonString);
        cleanByTree(element);
        jsonString = new GsonBuilder().disableHtmlEscaping().create().toJson(element);
        return jsonString;
    } catch (Exception e) {
        return jsonString;
    }
}

private static void cleanByTree(JsonElement e1) {
    if (e1 == null || e1.isJsonNull()) {

    } else if (e1.isJsonArray()) {
        for (Iterator<JsonElement> it = e1.getAsJsonArray().iterator(); it.hasNext(); ) {
            JsonElement e2 = it.next();
            if (e2 == null || e2.isJsonNull()) {
                //it.remove();
            } else if (e2.isJsonArray()) {
                if (e2.getAsJsonArray().size() == 0) {
                    it.remove();
                } else {
                    cleanByTree(e2);
                }
            } else if (e2.isJsonObject()) {
                cleanByTree(e2);
            }
        }
    } else {
        for (Iterator<Map.Entry<String, JsonElement>> it = e1.getAsJsonObject().entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, JsonElement> eIt = it.next();
            JsonElement e2 = eIt.getValue();
            if (e2 == null || e2.isJsonNull()) {
                //it.remove();
            } else if (e2.isJsonArray()) {
                if (e2.getAsJsonArray().size() == 0) {
                    it.remove();
                } else {
                    cleanByTree(e2);
                }
            } else if (e2.isJsonObject()) {
                cleanByTree(e2);
            }
        }
    }
}

}

相关问题