529 Stimmen

Deserialisieren eines List<T>-Objekts mit Gson?

Ich möchte ein Listenobjekt über Google Gson übertragen, aber ich weiß nicht, wie man generische Typen deserialisiert.

Was ich versucht habe, nachdem ich mir este (die Antwort von BalusC):

MyClass mc = new Gson().fromJson(result, new List<MyClass>() {}.getClass());

aber dann bekomme ich in Eclipse die Fehlermeldung "The type new List<MyClass>() {} muss die geerbte abstrakte Methode implementieren..." und wenn ich eine schnelle Lösung verwende, erhalte ich ein Monster von über 20 Methoden-Stubs.

Ich bin mir ziemlich sicher, dass es eine einfachere Lösung gibt, aber ich scheine sie nicht zu finden!

Jetzt habe ich das hier:

Type listType = new TypeToken<List<MyClass>>() {}.getType();

MyClass mc = new Gson().fromJson(result, listType);

Ich erhalte jedoch die folgende Ausnahme bei der fromJson Linie:

java.lang.NullPointerException
at org.apache.harmony.luni.lang.reflect.ListOfTypes.length(ListOfTypes.java:47)
at org.apache.harmony.luni.lang.reflect.ImplForType.toString(ImplForType.java:83)
at java.lang.StringBuilder.append(StringBuilder.java:203)
at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:56)
at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:88)
at com.google.gson.JsonDeserializationVisitor.visitUsingCustomHandler(JsonDeserializationVisitor.java:76)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:106)
at com.google.gson.JsonDeserializationContextDefault.fromJsonArray(JsonDeserializationContextDefault.java:64)
at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:49)
at com.google.gson.Gson.fromJson(Gson.java:568)
at com.google.gson.Gson.fromJson(Gson.java:515)
at com.google.gson.Gson.fromJson(Gson.java:484)
at com.google.gson.Gson.fromJson(Gson.java:434)

I hacer fangen JsonParseExceptions y result ist nicht null.

Ich überprüfte listType mit dem Debugger und erhielt folgendes Ergebnis:

  • list Type
    • args = ListOfTypes
      • list = null
      • resolvedTypes = Type[ 1 ]
    • loader = PathClassLoader
    • ownerType0 = null
    • ownerTypeRes = null
    • rawType = Class (java.util.ArrayList)
    • rawTypeName = "java.util.ArrayList"

Es scheint also, dass die getClass Aufrufen nicht richtig funktioniert hat. Irgendwelche Vorschläge...?

Ich habe die Gson Benutzerhandbuch . Es erwähnt eine Laufzeit-Ausnahme, die während des Parsens eines generischen Typs zu Json passieren sollte. Ich tat es "falsch" (nicht oben gezeigt), genau wie im Beispiel, aber nicht erhalten, dass Ausnahme überhaupt. Also änderte ich die Serialisierung wie im Benutzerhandbuch vorgeschlagen. Das hat aber nicht geholfen.

Editar:

Gelöst, siehe meine Antwort unten.

1voto

Ram Patro Punkte 111

Siehe Beispiel 2 für das Verständnis der Klasse "Typ" von Gson.

Beispiel 1: In diesem deserilizeResturant verwenden wir das Array Employee[] und erhalten die Details

public static void deserializeResturant(){

       String empList ="[{\"name\":\"Ram\",\"empId\":1},{\"name\":\"Surya\",\"empId\":2},{\"name\":\"Prasants\",\"empId\":3}]";
       Gson gson = new Gson();
       Employee[] emp = gson.fromJson(empList, Employee[].class);
       int numberOfElementInJson = emp.length();
       System.out.println("Total JSON Elements" + numberOfElementInJson);
       for(Employee e: emp){
           System.out.println(e.getName());
           System.out.println(e.getEmpId());
       }
   }

Beispiel 2:

//Above deserilizeResturant used Employee[] array but what if we need to use List<Employee>
public static void deserializeResturantUsingList(){

    String empList ="[{\"name\":\"Ram\",\"empId\":1},{\"name\":\"Surya\",\"empId\":2},{\"name\":\"Prasants\",\"empId\":3}]";
    Gson gson = new Gson();

    // Additionally we need to se the Type then only it accepts List<Employee> which we sent here empTypeList
    Type empTypeList = new TypeToken<ArrayList<Employee>>(){}.getType();

    List<Employee> emp = gson.fromJson(empList, empTypeList);
    int numberOfElementInJson = emp.size();
    System.out.println("Total JSON Elements" + numberOfElementInJson);
    for(Employee e: emp){
        System.out.println(e.getName());
        System.out.println(e.getEmpId());
    }
}

1voto

Peterstev Uremgba Punkte 619

Mit Kotlin können Sie einen generischen MutableList-Typ für alle benutzerdefinierten serialisierbaren Typen erhalten

private fun <T : Serializable> getGenericList(
    sharedPreferences: SharedPreferences,
    key: String,
    clazz: KClass<T>
): List<T> {
    return sharedPreferences.let { prefs ->
        val data = prefs.getString(key, null)
        val type: Type = TypeToken.getParameterized(MutableList::class.java, clazz.java).type
        gson.fromJson(data, type) as MutableList<T>
    }
}

können Sie diese Funktion aufrufen

getGenericList.(sharedPrefObj, sharedpref_key, GenericClass::class)

0voto

Andrei Punkte 771

In meinem Fall hat die Antwort von @uncaught_exceptions nicht funktioniert, ich musste die List.class anstelle von java.lang.reflect.Type :

String jsonDuplicatedItems = request.getSession().getAttribute("jsonDuplicatedItems").toString();
List<Map.Entry<Product, Integer>> entries = gson.fromJson(jsonDuplicatedItems, List.class);

0voto

oleg.cherednik Punkte 15389

Ich habe erstellt GsonUtils lib für diesen Fall. Ich füge diese in das zentrale Maven-Repository ein.

Map<String, SimpleStructure> expected = new HashMap<>();
expected.put("foo", new SimpleStructure("peperoni"));

String json = GsonUtils.writeValue(expected);

Map<String, SimpleStructure> actual = GsonUtils.readMap(json, String.class, SimpleStructure.class);

-1voto

mike83_dev Punkte 441

Die Antwort von kays1 hat mir gefallen, aber ich konnte sie nicht umsetzen. Also habe ich meine eigene Version mit seinem Konzept gebaut.

public class JsonListHelper{
    public static final <T> List<T> getList(String json) throws Exception {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        Type typeOfList = new TypeToken<List<T>>(){}.getType();
        return gson.fromJson(json, typeOfList);
    }
}

Verwendung:

List<MyClass> MyList= JsonListHelper.getList(jsonArrayString);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X