Chcę przeanalizować tablice JSON i użyć gson. Po pierwsze, mogę logować dane wyjściowe JSON, serwer wyraźnie odpowiada na klienta.
Oto moje wyjście JSON:
[
{
id : '1',
title: 'sample title',
....
},
{
id : '2',
title: 'sample title',
....
},
...
]
Wypróbowałem tę strukturę do analizy. Klasa zależna od pojedynczego array
i ArrayList
dla wszystkich JSONArray.
public class PostEntity {
private ArrayList<Post> postList = new ArrayList<Post>();
public List<Post> getPostList() {
return postList;
}
public void setPostList(List<Post> postList) {
this.postList = (ArrayList<Post>)postList;
}
}
Klasa poczty:
public class Post {
private String id;
private String title;
/* getters & setters */
}
Kiedy próbuję użyć gson bez błędu, bez ostrzeżenia i bez dziennika:
GsonBuilder gsonb = new GsonBuilder();
Gson gson = gsonb.create();
PostEntity postEnt;
JSONObject jsonObj = new JSONObject(jsonOutput);
postEnt = gson.fromJson(jsonObj.toString(), PostEntity.class);
Log.d("postLog", postEnt.getPostList().get(0).getId());
Co jest nie tak, jak mogę rozwiązać?
Szukałem sposobu na przeanalizowanie tablic obiektów w bardziej ogólny sposób; oto mój wkład:
CollectionDeserializer.java
:import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; public class CollectionDeserializer implements JsonDeserializer<Collection<?>> { @Override public Collection<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { Type realType = ((ParameterizedType)typeOfT).getActualTypeArguments()[0]; return parseAsArrayList(json, realType); } /** * @param serializedData * @param type * @return */ @SuppressWarnings("unchecked") public <T> ArrayList<T> parseAsArrayList(JsonElement json, T type) { ArrayList<T> newArray = new ArrayList<T>(); Gson gson = new Gson(); JsonArray array= json.getAsJsonArray(); Iterator<JsonElement> iterator = array.iterator(); while(iterator.hasNext()){ JsonElement json2 = (JsonElement)iterator.next(); T object = (T) gson.fromJson(json2, (Class<?>)type); newArray.add(object); } return newArray; } }
JSONParsingTest.java
:public class JSONParsingTest { List<World> worlds; @Test public void grantThatDeserializerWorksAndParseObjectArrays(){ String worldAsString = "{\"worlds\": [" + "{\"name\":\"name1\",\"id\":1}," + "{\"name\":\"name2\",\"id\":2}," + "{\"name\":\"name3\",\"id\":3}" + "]}"; GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Collection.class, new CollectionDeserializer()); Gson gson = builder.create(); Object decoded = gson.fromJson((String)worldAsString, JSONParsingTest.class); assertNotNull(decoded); assertTrue(JSONParsingTest.class.isInstance(decoded)); JSONParsingTest decodedObject = (JSONParsingTest)decoded; assertEquals(3, decodedObject.worlds.size()); assertEquals((Long)2L, decodedObject.worlds.get(1).getId()); } }
World.java
:public class World { private String name; private Long id; public void setName(String name) { this.name = name; } public String getName() { return name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
źródło
Konwersja w Object Array
Gson gson=new Gson(); ElementType [] refVar=gson.fromJson(jsonString,ElementType[].class);
Aby przekonwertować jako typ posta
Gson gson=new Gson(); Post [] refVar=gson.fromJson(jsonString,Post[].class);
Aby przeczytać to jako Listę obiektów, można użyć TypeToken
List<Post> posts=(List<Post>)gson.fromJson(jsonString, new TypeToken<List<Post>>(){}.getType());
źródło
Type listType = new TypeToken<List<Post>>() {}.getType(); List<Post> posts = new Gson().fromJson(jsonOutput.toString(), listType);
źródło
Niektóre odpowiedzi w tym poście są prawidłowe, ale za pomocą TypeToken biblioteka Gson generuje obiekty Tree z nierealnymi typami dla Twojej aplikacji.
Aby to uzyskać, musiałem odczytać tablicę i konwertować jeden po drugim obiekty wewnątrz tablicy. Oczywiście ta metoda nie jest najszybsza i nie polecam jej używać, jeśli macie za dużą tablicę, ale u mnie zadziałała.
Konieczne jest uwzględnienie w projekcie biblioteki Json. Jeśli tworzysz na Androida, jest to uwzględnione:
/** * Convert JSON string to a list of objects * @param sJson String sJson to be converted * @param tClass Class * @return List<T> list of objects generated or null if there was an error */ public static <T> List<T> convertFromJsonArray(String sJson, Class<T> tClass){ try{ Gson gson = new Gson(); List<T> listObjects = new ArrayList<>(); //read each object of array with Json library JSONArray jsonArray = new JSONArray(sJson); for(int i=0; i<jsonArray.length(); i++){ //get the object JSONObject jsonObject = jsonArray.getJSONObject(i); //get string of object from Json library to convert it to real object with Gson library listObjects.add(gson.fromJson(jsonObject.toString(), tClass)); } //return list with all generated objects return listObjects; }catch(Exception e){ e.printStackTrace(); } //error: return null return null; }
źródło
[ { id : '1', title: 'sample title', .... }, { id : '2', title: 'sample title', .... }, ... ]
Sprawdź kod Easy dla tego wyjścia
Gson gson=new GsonBuilder().create(); List<Post> list= Arrays.asList(gson.fromJson(yourResponse.toString,Post[].class));
źródło
Możesz to łatwo zrobić w Kotlinie za pomocą następującego kodu:
val fileData = "your_json_string" val gson = GsonBuilder().create() val packagesArray = gson.fromJson(fileData , Array<YourClass>::class.java).toList()
Zasadniczo wystarczy dostarczyć jeden
Array
zYourClass
obiektów.źródło
możesz pobrać wartość List bez używania obiektu Type .
EvalClassName[] evalClassName; ArrayList<EvalClassName> list; evalClassName= new Gson().fromJson(JSONArrayValue.toString(),EvalClassName[].class); list = new ArrayList<>(Arrays.asList(evalClassName));
Przetestowałem to i działa.
źródło
w Kotlinie :
val jsonArrayString = "['A','B','C']" val gson = Gson() val listType: Type = object : TypeToken<List<String?>?>() {}.getType() val stringList : List<String> = gson.fromJson( jsonArrayString, listType)
źródło