Java.util.Date的Gson反序列化器

hsvhsicv  于 2022-11-06  发布在  Java
关注(0)|答案(3)|浏览(226)

有人能让Deserializer工作吗?
我在方法deserialize中得到了完整的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);
}
zqry0prt

zqry0prt1#

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

wqnecbli2#

在这里,自定义的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;
    }
}
myss37ts

myss37ts3#

对于原始问题中的代码,无论使用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);
    }
  }
});

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

相关问题