用于java.util.Date的Gson反序列化器

时间:2011-12-28 01:19:38

标签: deserialization gson

有没有人让Deserializer工作?我在方法"反序列化"中获得完整的JSON表达式而不是元素??

    public static void main(String[] args) {
    GsonBuilder gb = new GsonBuilder();
    gb.registerTypeAdapter(DummyObject.class, new JsonSerializer<Date>() {
        public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
            System.out.println("serialize...");
            return new JsonPrimitive(DateUtil.toString(src));
        }
    });
    gb.registerTypeAdapter(DummyObject.class, new JsonDeserializer<Date>() {
        DateFormat format = DateFormat.getInstance();

        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            if (!(json instanceof JsonPrimitive)) {
                throw new JsonParseException("The date should be a string value");
            }

            try {
                return format.parse(json.getAsString());
            } catch (ParseException e) {
                throw new JsonParseException(e);
            }
        }
    });

    String jsonExp = "{\"createdDate\":\"2011-12-27T15:21:16\"}";
    Gson g = gb.create();
    DummyObject tf = g.fromJson(jsonExp, DummyObject.class);

}

3 个答案:

答案 0 :(得分:50)

Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssz")
.create();

答案 1 :(得分:2)

在这里,您可以使用自定义Gson构建器来处理几乎所有日期模式 使用JodaTime(如果不想使用它,可以排除它,它只是扩大了可能性)

public class MyGsonBuilder {

    public static <T> List<T> toList(String json, Class<T> clazz) {
        if (null == json) {
            return null;
        }
        Gson gson = build();
        return gson.fromJson(json, new TypeToken<T>() {
        }.getType());
    }

    private static boolean enableLog = false;


    private static void log(String log) {
        if (enableLog) Log.d("DEBUG_GSON_TIME", log);
    }

    static List<SimpleDateFormat> knownPatterns = new ArrayList<>(Arrays.asList(
            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"),
            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"),
            new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss"),
            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"),
            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
    ));

    static JsonSerializer<Date> ser = new JsonSerializer<Date>() {
        @Override
        public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
            return new GsonBuilder().create().toJsonTree(buildIso8601Format().format(src));
        }
    };


    static JsonDeserializer<Date> deser = new JsonDeserializer<Date>() {

        @Override
        public Date deserialize(JsonElement json, Type typeOfT,
                                JsonDeserializationContext context) throws JsonParseException {
            Date date = null;

            try {
                // Take a try
                String dateString = json.getAsJsonPrimitive().getAsString();
                log("deserialize date string = " + dateString);
                date = buildOddFormat().parse(dateString);
                log(" pattern (yyyy-MM-dd  HH:mm:ss) =  SUCCESS " + dateString + " = " + date.toString());
            } catch (Throwable t) {
                // Loop on
                log(" pattern (yyyy-MM-dd  HH:mm:ss) = error = " + t.getMessage());
            }

            if (date == null) {
                try {
                    // Take a try
                    String dateString = json.getAsJsonPrimitive().getAsString();
                    date = buildOldFormat().parse(dateString);
                    log(" pattern (MMM dd, yyyy HH:mm:ss) =  SUCCESS " + dateString + " = " + date.toString());
                } catch (Throwable t) {
                    // Loop on
                    log(" pattern (MMM dd, yyyy HH:mm:ss) = error = " + t.getMessage());
                }

            }
            if (date == null) {
                try {
                    // Take a try
                    String dateString = json.getAsJsonPrimitive().getAsString();
                    date = buildVeryOldFormat().parse(dateString);
                    log(" pattern (MMM d, yyyy HH:mm:ss) =  SUCCESS " + dateString + " = " + date.toString());
                } catch (Throwable t) {
                    // Loop on
                    log(" pattern (MMM d, yyyy HH:mm:ss) = error = " + t.getMessage());
                }

            }
            if (date == null)

                for (SimpleDateFormat pattern : knownPatterns) {
                    try {
                        // Take a try
                        if (!pattern.toPattern().contains("Z"))
                            pattern.setTimeZone(TimeZone.getTimeZone("UTC"));
                        String dateString = json.getAsJsonPrimitive().getAsString();
                        if (!pattern.toPattern().contains("Z"))
                            pattern.setTimeZone(TimeZone.getTimeZone("UTC"));
                        date = new Date(pattern.parse(dateString).getTime());
                        log(" pattern (" + pattern.toPattern() + ") =  SUCCESS " + dateString + " = " + date.toString());
                        break;
                    } catch (Throwable t) {
                        // Loop on
                        log(" pattern (" + pattern.toPattern() + ") = error = " + t.getMessage());
                    }
                }

//            }
            if (date == null) {
                try {
                    date = new Date(json.getAsJsonPrimitive().getAsLong());
                    log(" Joda =  SUCCESS " + json.getAsJsonPrimitive().getAsString() + " = " + date.toString());
                } catch (Throwable t) {
                    log(" pattern (Long) = error = " + t.getMessage());
                }
            }
            if (date == null) {
                try {
                    date = DateFormat.getInstance().parse(json.getAsJsonPrimitive().getAsString());
                    log(" Joda =  SUCCESS " + json.getAsJsonPrimitive().getAsString() + " = " + date.toString());
                } catch (Throwable t) {
                    log(" pattern ( DateFormat.getInstance().parse()) = error = " + t.getMessage());
                }
            }
            if (date == null) {
                DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
                try {
                    String dateString = json.getAsJsonPrimitive().getAsString();
                    date = fmt.parseDateTime(dateString).toDate();
                    log(" Joda =  SUCCESS " + dateString + " = " + date.toString());
                } catch (Throwable t) {
                    // Loop on
                    log(" Joda error = " + t.getMessage());
                    Crashlytics.logException(new Throwable("NON PARSABLE DATE!!! = " + json.toString()));
                }
            }

            if (date == null)
                date = new Date();

            return date;
        }
    };

    private static DateFormat buildIso8601Format() {
        DateFormat iso8601Format = new SimpleDateFormat(
                "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        return iso8601Format;
    }

    private static DateFormat buildOddFormat() {
        DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
        iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
        return iso8601Format;
    }

    private static DateFormat buildOldFormat() {
        DateFormat iso8601Format = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss");
        iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
        return iso8601Format;
    }

    private static DateFormat buildVeryOldFormat() {
        DateFormat iso8601Format = new SimpleDateFormat("MMM d, yyyy HH:mm:ss");
        iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
        return iso8601Format;
    }

    static public Gson build() {
        Gson gson = new GsonBuilder()
                //.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
                .registerTypeAdapter(Date.class, deser)
                .registerTypeAdapter(Date.class, ser)
                .excludeFieldsWithoutExposeAnnotation()
                .create();
        return gson;
    }
}

答案 2 :(得分:-2)

使用原始问题中的代码,使用Gson 1.7.1或Gson 2.0,我得到的是“线程中的异常”main“com.google.gson.JsonParseException:日期应该是字符串值”。这就是我期望编写的代码。

我猜你可能想为java.util.Date注册一个类型适配器,而不是DummyObject。 (这导致了一个不同的错误,但我认为它更接近你想要实现的目标。当然,我正在猜测问题/代码的意图。)

或许您想要沿着以下几行更改反序列化逻辑,理解您只想将JSON的日期部分反序列化为java.util.Date

gb.registerTypeAdapter(DummyObject.class, new JsonDeserializer<Date>()
{
  DateFormat format = DateFormat.getInstance();

  public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException
  {
    try
    {
      return format.parse(((JsonObject)json).get("createdDate").getAsString());
    }
    catch (ParseException e)
    {
      throw new JsonParseException(e);
    }
  }
});

您仍然需要解决(更具体的)日期解析错误。