GSON deserializa la clave-valor para el objeto personalizado

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 .

MyCustomClass.java

 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 + "}"; } } 

MyCustomDeserializer.java

 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); } } 

GsonTest.java

 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); } }