【问题标题】:Gson Deserializer for java.util.Datejava.util.Date 的 Gson 反序列化器
【发布时间】:2011-12-28 01:19:37
【问题描述】:

有人让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);
}

【问题讨论】:

    标签: deserialization gson


    【解决方案1】:
    Gson gson = new GsonBuilder()
    .setDateFormat("yyyy-MM-dd'T'HH:mm:ssz")
    .create();
    

    【讨论】:

    • 很想知道如何配置 Spring 所以它会这样做。
    • 这没有任何作用。
    【解决方案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;
        }
    }
    

    【讨论】:

      【解决方案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);
          }
        }
      });
      

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

      【讨论】:

      • 如果 JSON 表达式包含映射到“DummyObject”的其他字段,并且其中一个字段表示为日期。?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-11
      相关资源
      最近更新 更多