"Unparseable date: 1302828677828" intentando deserializar con Gson una fecha de formato milisegundo recibida del servidor
Después de 4 horas sin parar tratando de resolver el problema he decidido preguntar aquí si alguien podría ayudarme.
El problema es que mi cliente Android cuando intenta deserializar los datos recibidos de un servidor lanzan la excepción "Unparseable: 1302828677828".
- Cómo serializar para la clase android.location?
- Envío de un objeto serializado de Android a un servlet utilizando cliente HTTP
- Uso de genéricos en código Java de Android
- Rendimiento de la serialización y Google Android
- ¿Por qué un Comparator debería implementar Serializable?
Me gustaría saber si es posible deserializar una fecha de formato de milisegundos usando Gson.
- Android: cómo almacenar persistentemente un Spanned?
- Excepción Cast de clase al pasar una matriz de Serializables de una actividad a otra
- Android cómo guardar un mapa de bits - código de buggy
- Escribir objeto en el almacenamiento interno en android (Dentro del nuevo directorio)
- Conversión de mapa de bits Java a matriz de bytes
- Java.io.NotSerializableException incluso si implemento "Serializable"
- Android java.lang.IllegalArgumentException: no hay campo de caracteres 'exponencial' en android 2.3
Comentario de Alfonso:
Finalmente conseguí la solución:
// Creates the json object which will manage the information received GsonBuilder builder = new GsonBuilder(); // Register an adapter to manage the date types as long values builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return new Date(json.getAsJsonPrimitive().getAsLong()); } }); Gson gson = builder.create();
Tengo el mismo problema cuando intenté deserialize el campo de DateTime con el cliente del resto de la biblioteca de las anotaciones de Androide . Como una solución que he creado GsonHttpMessageConverter personalizado
public class CustomGsonHttpMessageConverter extends GsonHttpMessageConverter { public CustomGsonHttpMessageConverter() { // Creates the json object which will manage the information received GsonBuilder builder = new GsonBuilder(); // Register an adapter to manage the date types as long values builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return new Date(json.getAsJsonPrimitive().getAsLong()); } }); setGson(builder.create()); } }
Y definirlo en el cliente de descanso
@Rest(rootUrl = "http://192.168.1.1:8080", converters = {CustomGsonHttpMessageConverter.class}) public interface RestClient extends RestClientErrorHandling { ...
Espero que sea util
Escribí un ImprovedDateTypeAdapter basado en GSON default DateTypeAdapter que soporta el formato de fechas predeterminado y el formato de fecha y hora (largo).
import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.google.gson.TypeAdapter; import com.google.gson.TypeAdapterFactory; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; public final class ImprovedDateTypeAdapter extends TypeAdapter<Date> { public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) { @SuppressWarnings("unchecked") TypeAdapter<T> typeAdapter = (TypeAdapter<T>) ((typeToken.getRawType() == Date.class) ? new ImprovedDateTypeAdapter() : null); return typeAdapter; } }; private final DateFormat enUsFormat; private final DateFormat localFormat; private final DateFormat iso8601Format; public ImprovedDateTypeAdapter() { this.enUsFormat = DateFormat.getDateTimeInstance(2, 2, Locale.US); this.localFormat = DateFormat.getDateTimeInstance(2, 2); this.iso8601Format = buildIso8601Format(); } private static DateFormat buildIso8601Format() { DateFormat iso8601Format = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC")); return iso8601Format; } public Date read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } return deserializeToDate(in.nextString()); } private synchronized Date deserializeToDate(String json) { try { return new Date(Long.parseLong(json)); } catch (Exception e) { try { return this.localFormat.parse(json); } catch (ParseException e1) { try { return this.enUsFormat.parse(json); } catch (ParseException e2) { try { return this.iso8601Format.parse(json); } catch (ParseException e3) { throw new JsonSyntaxException(json, e3); } } } } } public synchronized void write(JsonWriter out, Date value) throws IOException { if (value == null) { out.nullValue(); return; } String dateFormatAsString = this.enUsFormat.format(value); out.value(dateFormatAsString); } }
Para usarlo:
// Creates the json object which will manage the information received GsonBuilder builder = new GsonBuilder(); // Register an adapter to manage the date types as long values builder.registerTypeAdapter(Date.class, new ImprovedDateTypeAdapter()); Gson gson = builder.create();