GSON将键值反序列化为自定义对象

我需要反序列化json,这是一个日期/长值数组。 以下是返回的JSON的示例:

[{"2011-04-30T00:00:00-07:00":100}, {"2011-04-29T00:00:00-07:00":200}] 

使用GSON我可以将它反序列化为List<Map> ,但是希望能够将它转换为List类似于:

 public class MyCustomClass() { Date date; Long value; } 

我似乎无法找到一种方法来指示GSON将JSON映射的键/值映射到我的自定义类中的日期/值字段。 有没有办法做到这一点,或者是地图列表唯一的路线?

您需要编写自定义反序列化程序。 您还需要使用SimpleDateFormat可以实际解析的时区格式。 zZ都不匹配-07:00 ,这是RFC 822时区格式( -0700 )或“一般时区”( Mountain Standard TimeMSTGMT-07:00 )的奇怪组合。 或者,您可以使用完全相同的时区格式,并使用JodaTime的DateTimeFormat

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

所有上面的代码都在Github上 ,随意克隆(尽管你也可以获得其他问题的答案代码)。

非常类似Matts的回答,但使用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); } }