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
可以实际解析的时区格式。 z
和Z
都不匹配-07:00
,这是RFC 822时区格式( -0700
)或“一般时区”( Mountain Standard Time
或MST
或GMT-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); } }