2011-12-28 18 views
11

有沒有人得到Deserializer的工作?我在方法「反序列化」而不是元素獲得完整的JSON表達式?用於java.util.Date的Gson Deserializer

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

} 

回答

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

最後的小'z'可能是ISO格式化的日期時間字符串的問題,因爲時區可能是Z或+00:00,SimpleDateFormat無法正確處理 – Lucas 2014-11-30 16:02:34

+0

想知道如何配置Spring,因此它會這樣做。 – user1944491 2015-06-10 13:57:54

+0

完美答案.....投了1 – sonida 2016-01-28 18:36:10

-2

隨着原題的代碼,即使用GSON 1.7.1或2.0 GSON,我得到的是「異常線程‘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); 
    } 
    } 
}); 

您仍然需要解決(更具體的)日期解析錯誤。

+0

如果JSON表達包含映射到可以說「DummyObject」的其他字段,其中一個字段表示爲日期。 – gpa 2011-12-28 17:29:26

0

在這裏你去,定製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; 
    } 
}