2016-03-29 3 views
0

Nun, ich habe das: Eine Reihe von Webservices, jeder Webservice gibt ein Array von einer Entität zurück. Gut!Java: Dynamischer Listentyp zum JServerarray

In meiner Android App rufe ich die Webservices an und erhalte die JSON String mit dem Array von Elementen.

Um es einige dynamisch ich ein Array mit den gegossenen Klassen Namen gemacht, Beispiel:

<item>com.company.package.Person</item> 
<item>com.company.package.Animal</item> 
<item>com.company.package.Thing</item> 
// etc 

Die Idee war:

  1. Legen Sie das Array mit dem Namen der Klasse zu werfen die JSON

    String[] entities = getResources().getStringArray(R.array.classNames); 
    
  2. ein Klasse-Typ Setzen Sie sich mit Class.forName(...)

    Class<?> object = Class.forName(entities[y]); 
    
  3. Immer die Web Service gibt einen Array, dann mag ich, wie dieses

    //see the **object**, this was my idea but doesn't work 
    Type type = new TypeToken<List<**object**>() {}.getType(); 
    List<**object**> array = gson.fromJson(jsonArrayString, type); 
    

irgendeine Weise die Json zu Java Liste konvertieren, dies zu tun?

Dies funktioniert

ich einen Weg, es

schreiben meine eigene ParameterizedType Liste zu tun gefunden (@ andersschuller Antwort) und mit diesem

Class<?> clazz = Class.forName(entities[y]); 
Type type = new ParameterizedTypeList(clazz.newInstance().getClass()); 
List<? extends Object> array = SystemUtils.factoryGson().fromJson(datos.get(y).toString(), type); 

Mein Problem wurde gelöst mit 3 Zeilen (vielleicht weniger als das)

Hoffen Sie, dass jemand hilft!

+0

ich Ihre Frage falsch verstanden haben, aber Sie brauchen nicht ein Typ e zum Deserialisieren von JSonsachen. Sie können auch normale Klassen verwenden. siehe [link] (https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/Gson.html # fromJson (java.lang.String,% 20java.lang.Class)) – Distjubo

+0

Auch [Klasse] (http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class .html) implementiert [Type] (https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Type.html). – Distjubo

Antwort

1

Ich glaube, es gibt keine Möglichkeit zu tun, was Sie mit der TypeToken zu tun versuchen. GSON kann jedoch tatsächlich jedes ParameterizedType verarbeiten, das an das gson.fromJson-Verfahren übergeben wird, und es ist relativ einfach, diese Schnittstelle zu implementieren.

In Ihrem speziellen Fall wollen wir eine Art, dessen rohen Typ Argument List und dessen Typs entweder Person, Animal oder Thing bauen. Die folgende Klasse ermöglicht es uns, solche Typen zu bauen:

public static class ListType implements ParameterizedType { 
    private final Class<?> elementClass; 

    public ListType(Class<?> elementClass) { 
     this.elementClass = elementClass; 
    } 

    @Override 
    public Type[] getActualTypeArguments() { 
     return new Type[]{elementClass}; 
    } 

    @Override 
    public Type getRawType() { 
     return List.class; 
    } 

    @Override 
    public Type getOwnerType() { 
     return null; 
    } 
} 

Angenommen, wir dann einige JSON haben wie

String json = "[{\"name\": \"Charlie\"}]"; 

und Person und Animal Klassen, die einen „Namen“ Eigenschaft haben, können wir dann deserialisieren diese JSON in Listen durch eine entsprechende ListType Instanz mit:

List<Person> people = gson.fromJson(json, new ListType(Person.class)); 
System.out.println(people.get(0).getClass().getSimpleName());   // prints Person 
System.out.println(people.get(0).name);         // prints Charlie 

List<Animal> animals = gson.fromJson(json, new ListType(Animal.class)); 
System.out.println(animals.get(0).getClass().getSimpleName());   // prints Animal 
System.out.println(animals.get(0).name);         // prints Charlie 
+0

Ich möchte nicht den Klassennamen ('Person') schreiben müssen, ich möchte den Argumenttyp mit' Class.forName ("class.name") '(oder so ähnlich) laden und dynamisch injizieren. Ich habe viele Arten von Objekten und ich möchte mein Problem mit nicht mehr als 5 Zeilen lösen :) (Wenn das möglich ist) –

+0

Sie können einfach die dynamisch geladene Klasse in den 'ListType'-Konstruktor übergeben. Natürlich können Sie nicht wissen, um welchen Typ es sich beim Kompilieren handelt, also haben Sie 'List objects = gson.fromJson (json, neuer ListType (Class.forName (" ... ")))' – andersschuller

+0

Ich habe etwas gemacht, mehr Zeilen: 'Klasse clazz = Class.forName (entities [y]);' und der 'Type' wie folgt' Type type = new ParameterizedTypeList (clazz.newInstance(). GetClass()); 'und es funktioniert. –

Verwandte Themen