leer - libreria json java
Cómo analizar matriz JSON con Gson (4)
Algunas de las respuestas de esta publicación son válidas, pero al utilizar TypeToken, la biblioteca Gson genera un objeto Árbol con tipos irreales para su aplicación.
Para obtenerlo, tuve que leer la matriz y convertir uno por uno los objetos dentro de la matriz. Por supuesto, este método no es el más rápido y no recomiendo usarlo si tienes una matriz demasiado grande, pero funcionó para mí.
Es necesario incluir la biblioteca Json en el proyecto. Si está desarrollando en Android, está incluido:
/**
* 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;
}
Quiero analizar arreglos JSON y usar gson. En primer lugar, puedo registrar la salida JSON, el servidor responde claramente al cliente.
Aquí está mi salida JSON:
[
{
id : ''1'',
title: ''sample title'',
....
},
{
id : ''2'',
title: ''sample title'',
....
},
...
]
Intenté esta estructura para analizar. Una clase, que depende de una única array
y ArrayList
para todos 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;
}
}
Clase postal:
public class Post {
private String id;
private String title;
/* getters & setters */
}
Cuando trato de usar gson, no hay error, no hay advertencia y no hay registro:
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());
¿Qué pasa, cómo puedo resolverlo?
Estaba buscando una forma de analizar matrices de objetos de una manera más genérica; aquí está mi contribución:
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;
}
}
Puede analizar el JSONArray
directamente, no necesita envolver su clase Post
con PostEntity
una vez más y no necesita el nuevo JSONObject().toString()
:
Gson gson = new Gson();
String jsonOutput = "Your JSON String";
Type listType = new TypeToken<List<Post>>(){}.getType();
List<Post> posts = gson.fromJson(jsonOutput, listType);
Espero que ayude.
Type listType = new TypeToken<List<Post>>() {}.getType();
List<Post> posts = new Gson().fromJson(jsonOutput.toString(), listType);