¿Cómo puedo deserializar un objeto JSON pero mantener un campo específico como una cadena en lugar de un objeto anidado?

Tengo una estructura de json que he pegado abajo. Me gustaría deserializar el json en un POJO de java con Gson que es bastante sencillo, excepto que quiero mantener uno de los campos, data , como un tipo de cadena en lugar de un objeto anidado.

Estructura JSON

 { "created_on": "2015-06-04T16:12:04-0700", "modified_on": "2015-06-04T16:12:09-0700", "identifier": "sample", "name": "some name", "summary": "some summary", "data": { "$type": "a_type", "some_other_stuff": { "more_stuff": "lorem ipsum" }, "type2": { "$type": "another_type", "other_stuff": { "event_more_stuff": "lorem ipsum" } } } } 

Mi POJO se vería así:

 public class Sample { private String identifier; // "sample" private String created_on; // "2015-06-04T16:12:04-0700" private String modified_on; // "2015-06-04T16:12:09-0700" private String name; // "some name" private String summary; // "some summary" private String data; // "{ \"$type\": ... }" // getters and setters } 

El campo de data debe permanecer como una cadena con formato JSON.

He intentado implementar un Custom TypeAdapter y leer el campo como una cadena, pero falla con Expected a string but was BEGIN_OBJECT .

También tenga en cuenta, me gustaría que la estructura se mantenga en la serialización también – para que pueda serializar el POJO de nuevo a la estructura original de JSON.

Editar TypeAdapter personalizado:

 public class SampleTypeAdapter extends TypeAdapter<Sample> { @Override public void write(JsonWriter out, Sample sample) throws IOException { out.beginObject(); out.name("identifier").value(sample.getIdentifier()); out.name("name").value(sample.getName()); out.name("data").value(sample.getData()); out.name("summary").value(sample.getSummary()); out.name("modified_on").value(sample.getModifiedOn()); out.name("created_on").value(sample.getCreatedOn()); out.endObject(); } @Override public Sample read(JsonReader in) throws IOException { final Sample sample = new Sample(); in.beginObject(); while (in.hasNext()) { String nextName = in.nextName(); switch (nextName) { case "identifier": sample.setIdentifier(in.nextString()); break; case "name": sample.setName(in.nextString()); break; case "data": sample.setData(in.nextString()); // <-- fails here break; case "summary": sample.setSummary(in.nextString()); break; case "modified_on": sample.setModifiedOn(in.nextString()); break; case "created_on": sample.setCreatedOn(in.nextString()); break; default: in.skipValue(); break; } } in.endObject(); return sample; } } 

2 Solutions collect form web for “¿Cómo puedo deserializar un objeto JSON pero mantener un campo específico como una cadena en lugar de un objeto anidado?”

Puede crear un JsonDeserializer personalizado como éste:

 public class SampleGSONParserAdapter implements JsonDeserializer<Sample> { @Override public Sample deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { Sample sample = new Sample(); JsonObject sampleJsonObject = json.getAsJsonObject(); sample.setName(sampleJsonObject.get("name").getAsString()); // do the other parsing stuff here.. // getting the data object as a string sample.setJsonString(sampleJsonObject.get("data").toString()); return sample; } } 

Y lo usas así:

 GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Sample.class, new SampleGSONParserAdapter()); Gson gson = gsonBuilder.create(); 

La parte mala es que no es tan rápido como el que usted escribió pero por lo menos usted puede hacer el analizar de encargo como éste.

Utilice esta clase personalizada, añada lo que necesita:

  public class JsonParser { public static <T> List<T> parseList(String json_text, String json_path, Class<T> c) { Gson gson = new Gson(); try { List<T> json_list = new ArrayList<>(); List<Object> nodes = JsonPath.read(json_text, json_path); for(Object node : nodes) { json_list.add(gson.fromJson(node.toString(), c)); } return (json_list); } catch(Exception e) { return (new ArrayList<>()); } } public static <T> T parseObject(String json_text, Class<T> c) { return (new Gson()).fromJson(json_text, c); } public static <T> T getItemAtPosition (String json_text, String json_path) { try { return (JsonPath.read(json_text, json_path)); } catch(Exception e) { return (null); } } } 

EDICIÓN FINAL:

Puesto que lo que quieres es sólo parte de tu JSON para seguir siendo una cadena JSONed, de todo esto solo necesitas (lo que significa solo JsonPath ):

 String myData = JsonParser.getItemAtPosition(response,"$.data[*]").toString(); 
  • Parse Json en el estudio android de String
  • Cómo sacar datos JSON correctamente usando PHP
  • Retrofit: Se esperaba BEGIN_OBJECT pero era BEGIN_ARRAY
  • Valor de Json Parsing y Nullable int en android
  • ¿Cómo mantener el inicio de sesión del servidor en toda la aplicación nativa de Android?
  • Desarrollar sitios web con la misma API que los móviles
  • Cómo comprimir JSON con gzip en Rails para Android?
  • GSON evitar el JsonSyntaxException devolver el mapeo parcial
  • ¿Cómo puedo obtener la respuesta JSON de una solicitud POST en un WebView?
  • Analizar matriz anidada dinámica en Android Retrofit
  • JSON a java utilizando gson
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.