Necesito deserializar json, que es una matriz de valores de fecha / largo. Aquí hay un ejemplo del JSON devuelto:
[{"2011-04-30T00:00:00-07:00":100}, {"2011-04-29T00:00:00-07:00":200}]
Usando GSON puedo deserializar esto en una List<Map>
, pero me gustaría poder convertirlo a una List
similar a:
public class MyCustomClass() { Date date; Long value; }
Parece que no puedo encontrar la manera de ordenar a GSON que asigne la clave / valor del mapa JSON a los campos de fecha / valor en mi clase personalizada. ¿Hay alguna manera de hacer esto o una lista de mapas es la única?
Necesita escribir un deserializador personalizado. También necesita utilizar un formato de zona horaria que SimpleDateFormat
puede analizar. Ni z
ni Z
coincidirán con -07:00
, que es una combinación extraña de formato de zona horaria RFC 822 ( -0700
) o una “zona horaria general” ( Mountain Standard Time
o MST
o GMT-07:00
). Alternativamente, puede mantener el mismo formato de zona horaria y usar DateTimeFormat
de JodaTime .
public class MyCustomClass { Date date; Long value; public MyCustomClass (Date date, Long value) { this.date = date; this.value = value; } @Override public String toString() { return "{date: " + date + ", value: " + value + "}"; } }
public class MyCustomDeserializer implements JsonDeserializer { private DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"); @Override public MyCustomClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) throws JsonParseException { JsonObject obj = json.getAsJsonObject(); Entry entry = obj.entrySet().iterator().next(); if (entry == null) return null; Date date; try { date = df.parse(entry.getKey()); } catch (ParseException e) { e.printStackTrace(); date = null; } Long value = entry.getValue().getAsLong(); return new MyCustomClass(date, value); } }
public class GsonTest { public static void main(String[] args) { // Note the time zone format tweak (removed the ':') String json = "[{\"2011-04-30T00:00:00-0700\":100}, {\"2011-04-29T00:00:00-0700\":200}]"; Gson gson = new GsonBuilder() .registerTypeAdapter(MyCustomClass.class, new MyCustomDeserializer()) .create(); Type collectionType = new TypeToken>(){}.getType(); Collection myCustomClasses = gson.fromJson(json, collectionType); System.out.println(myCustomClasses); } }
Todo el código anterior está en Github , siéntete libre de clonar (aunque obtendrás el código para las respuestas a otras preguntas también).
Muy similar a la respuesta de Matts pero usando Joda:
import java.lang.reflect.Type; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; public class DateTimeSerializer implements JsonDeserializer { private DateTimeFormatter parser = DateTimeFormat.forPattern("YYYY-MM-dd'T'HH:mm:ss.SS'Z'").withZoneUTC(); @Override public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) throws JsonParseException { String dateTimeString = ctx.eserialize(json, String.class); return parser.parseDateTime(dateTimeString); } }