Gson Deserializer для java.util.Date

Кто-нибудь получил Deserializer? Я получаю полное выражение JSON в методе "deserialize" вместо элемента??

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

}

Ответ 1

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

Ответ 2

Здесь вы, пользовательский Gson builder, который обрабатывает почти каждый шаблон даты используя 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;
    }
}

Ответ 3

С кодом в исходном вопросе, используя 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);
    }
  }
});

Вам все равно придется разрешить (более конкретную) ошибку синтаксического анализа даты.