Gson, cómo deserializar matriz o cadena vacía
Estoy tratando de deserializar este json a la matriz de objetos:
[{ "name": "item 1", "tags": ["tag1"] }, { "name": "item 2", "tags": ["tag1","tag2"] }, { "name": "item 3", "tags": [] }, { "name": "item 4", "tags": "" }]
Mi clase de java se ve así:
- ¿Cómo enviar un JSONObject a un servicio REST?
- Parse ~ 1 MB JSON en Android muy lento
- Problema de desplazamiento Infinito Infinito de RecyclerView
- Obtener el valor de cadena de un objeto de matriz JSON en Java
- Conversión de JSON a objeto Java mediante Gson
public class MyObject { @Expose private String name; @Expose private List<String> tags = new ArrayList<String>(); }
El problema es la propiedad de las etiquetas de json, que puede ser una cadena o una matriz vacía. Ahora mismo gson me da error: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING
¿Cómo debo deserializar este json?
No tengo ningún control para este json, viene de 3er api pary.
- Org.json.JSONException: Valor <! DOCTYPE de tipo java.lang.String no se puede convertir en JSONObject
- Pojo analiza gson con nombres de java no válidos
- Extraer el cuerpo del mensaje de HttpResponse
- Actualizar elementos en un objeto JSONO
- Configuración de la tarea asincrónica para cargar Json en una vista de lista
- ¿Cómo puedo hacer una petición Volley JSONObject con un objeto personalizado como parámetro?
- ¿Cómo puedo eliminar un elemento específico de un JSONArray?
- No puedo trabajar con Jackson
No tengo ningún control para este json, viene de 3er api pary.
Si no tienes el control sobre los datos, la mejor solución es crear un deserializador personalizado en mi opinión:
class MyObjectDeserializer implements JsonDeserializer<MyObject> { @Override public MyObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jObj = json.getAsJsonObject(); JsonElement jElement = jObj.get("tags"); List<String> tags = Collections.emptyList(); if(jElement.isJsonArray()) { tags = context.deserialize(jElement.getAsJsonArray(), new TypeToken<List<String>>(){}.getType()); } //assuming there is an appropriate constructor return new MyObject(jObj.getAsJsonPrimitive("name").getAsString(), tags); } }
Lo que hace que compruebe si "tags"
es un JsonArray
o no. Si es el caso, lo deserializa como de costumbre, de lo contrario no lo toca y simplemente crear su objeto con una lista vacía.
Una vez que hayas escrito eso, necesitas registrarlo en el analizador JSON:
Gson gson = new GsonBuilder().registerTypeAdapter(MyObject.class, new MyObjectDeserializer()).create(); //here json is a String that contains your input List<MyObject> myObjects = gson.fromJson(json, new TypeToken<List<MyObject>>(){}.getType());
Ejecutándolo, consigo como salida:
MyObject{name='item 1', tags=[tag1]} MyObject{name='item 2', tags=[tag1, tag2]} MyObject{name='item 3', tags=[]} MyObject{name='item 4', tags=[]}
Antes de convertir el json en objeto, sustituya la cadena "tags": ""
por "tags": []
Estás mezclando tipos de datos. No puedes tener tanto un Array como una cadena. Cambio
"tags": ""
a
"tags": null
Y usted es bueno para ir.
Utilizar Jacskon Object Mapper
Vea un ejemplo sencillo
[ http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/%5D%5B1%5D
Utilice el método fromJson () de GSON para serializar su JSON.
Usted puede entender mejor esto por el ejemplo dado abajo:
import java.util.ArrayList; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; public class JsonToJava { /** * @param args */ public static void main(String[] args) { String json = "[{\"firstName\":\"John\", \"lastName\":\"Doe\", \"id\":[\"10\",\"20\",\"30\"]}," + "{\"firstName\":\"Anna\", \"lastName\":\"Smith\", \"id\":[\"40\",\"50\",\"60\"]}," + "{\"firstName\":\"Peter\", \"lastName\":\"Jones\", \"id\":[\"70\",\"80\",\"90\"]}," + "{\"firstName\":\"Ankur\", \"lastName\":\"Mahajan\", \"id\":[\"100\",\"200\",\"300\"]}," + "{\"firstName\":\"Abhishek\", \"lastName\":\"Mahajan\", \"id\":[\"400\",\"500\",\"600\"]}]"; jsonToJava(json); } private static void jsonToJava(String json) { Gson gson = new Gson(); JsonParser parser = new JsonParser(); JsonArray jArray = parser.parse(json).getAsJsonArray(); ArrayList<POJO> lcs = new ArrayList<POJO>(); for (JsonElement obj : jArray) { POJO cse = gson.fromJson(obj, POJO.class); lcs.add(cse); } for (POJO pojo : lcs) { System.out.println(pojo.getFirstName() + ", " + pojo.getLastName() + ", " + pojo.getId()); } }
}
Clase POJO:
public class POJO { private String firstName; private String lastName; private String[] id; //Getters and Setters.
Espero que esto solucione su problema.
La seguridad tipo Jackson es mucho mejor que Gson. A veces se stackoverflow en Gson.