【问题标题】:GSON deserializing key-value to custom objectGSON 将键值反序列化为自定义对象
【发布时间】:2011-05-01 01:43:20
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 除非你的文档看起来像[{"date":"2011"2011-04-30T00:00:00-07:00","value":100}, {"date":"2011-04-29T00:00:00-07:00","value":200}]
  • @lobster:真的吗?我的回答另有说明(并在您发表评论之前发布)
  • @Matt - 我的解决方案是在输入端,如果他的文档是我推荐的方式,他可以直接完成gson.fromJSON(inputJson, List<MyCustomClass.class>) 而无需经过大量代码。但我同意,您的解决方案更通用,可以立即满足他的需求。

标签: java serialization gson deserialization


【解决方案1】:

您需要编写一个自定义反序列化器。您还需要使用SimpleDateFormat 可以实际解析的时区格式。 zZ 都不会匹配 -07:00,这是 RFC 822 时区格式 (-0700) 或“一般时区”(Mountain Standard TimeMSTGMT-07:00)的奇怪组合.或者,您可以坚持使用完全相同的时区格式,以及use JodaTime's 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<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);
    }
}

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

以上所有代码都是on Github,请随意克隆(尽管您也会获得其他问题的答案代码)。

【讨论】:

    【解决方案2】:

    与 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<DateTime> {
    
        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);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多