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

Ric*_*oll 18 java serialization gson deserialization

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

[{"2011-04-30T00:00:00-07:00":100}, {"2011-04-29T00:00:00-07:00":200}]
Run Code Online (Sandbox Code Playgroud)

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

public class MyCustomClass() { 
    Date date;
    Long value;
}
Run Code Online (Sandbox Code Playgroud)

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

Mat*_*all 23

您需要编写自定义反序列化程序.您还需要使用SimpleDateFormat可以实际解析的时区格式.既z不会也不Z匹配-07:00,这是RFC 822时区格式(-0700)或"通用时区"(Mountain Standard TimeMSTGMT-07:00)的奇怪组合.或者,您可以使用完全相同的时区格式,并使用JodaTimeDateTimeFormat.

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 + "}";
    }
}
Run Code Online (Sandbox Code Playgroud)

MyCustomDeserializer.java

public class MyCustomDeserializer implements JsonDeserializer<MyCustomClass>
{
    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<String, JsonElement> 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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<Collection<MyCustomClass>>(){}.getType();
        Collection<MyCustomClass> myCustomClasses = gson.fromJson(json, collectionType);
        System.out.println(myCustomClasses);
    }
}
Run Code Online (Sandbox Code Playgroud)

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