2011-12-28 25 views
11

¿Alguien consiguió Deserializer trabajando? Estoy obteniendo una expresión JSON completa en el método "deserialize" en lugar de element ??Deserializador Gson para java.util.Date

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

} 

Respuesta

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

la pequeña 'z' al final podría ser un problema para las cadenas de fecha y hora con formato ISO, ya que la zona horaria podría ser Z o +00: 00 que SimpleDateFormat – Lucas

+0

no puede manejar correctamente. Me encantaría saber cómo configurar Spring para que lo haga. – user1944491

+0

respuesta perfecta ..... votado 1 – sonida

-2

Con el código en la pregunta original, utilizando Gson 1.7.1 o 2.0 Gson, lo único que consigue es "Excepción en el hilo '' com.google.gson.JsonParseException principal: La fecha debe ser una cadena valor". Esto es lo que espero que el código tal como está escrito.

Supongo que es posible que desee registrar un adaptador de tipo para java.util.Date, y no para DummyObject. (Esto lleva a un error diferente, pero creo que está más cerca de lo que está tratando de lograr. Por supuesto, estoy adivinando un poco sobre la intención de la pregunta/código.)

O tal vez quiera cambie la lógica de deserialización a lo largo de las siguientes líneas, entendiendo que solo desea deserializar la parte de la fecha del JSON en un 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); 
    } 
    } 
}); 

Deberá resolver el error de análisis de fecha (más específico).

+0

Si JSON Expresión contiene otros campos a los que se asigna el nombre "DummyObject" y uno del campo se representa como date. – gpa

0

Aquí tiene, a medida que se ocupa de Gson constructor patrón de casi todos los fecha usando JodaTime (puede excluirlo si no quieren usarlo, simplemente ampliar las posibilidades)

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