Al ver esta semana el post de @Chalalo en geeks sobre cómo acceder desde Android a servicios SOAP (*.asmx) de .Net, me he acordado que tenía pendiente escribir una pequeña nota sobre algo que me dio un pequeño dolor de cabeza en su momento: cómo deserializar las fechas que nos devuelve un servicio .Net y convertirlas en un objeto Date en Android.
Los tipos básicos (enteros, strings, …) se deserializan sin problemas, pero las fechas dan problemas porque cuando se serializan desde .Net en JSon, se hace como “Date(longDeTicks)”. Esto es perfecto para JavaScript, porque se interpreta esa llamada y se obtiene el objeto Date esperado, pero en Java esto no se interpreta.
¿Cómo lo resolví? “Muy sencillo”. Tan sólo usé el parser GSon y se le registra un adaptador para el tipo Date, para que sepa como serializar y deserializar objetos de ese tipo. Para hacer esto, hay que registrar el adaptador al crear el parser:
Gson gson = new GsonBuilder() .registerTypeAdapter(Date.class, new GsonDateAdapter()) .create();
El adaptador en sí es muy sencillo, y puede server de base para permitir serializar y deserializar desde Android objetos complejos:
public class GsonDateAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> { public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) { String string = "/Date(" + Long.toString(src.getTime()) + ")/"; return new JsonPrimitive(string); } 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"); } String aux = json.getAsString(); aux = aux.substring(6, aux.length() - 2); return new Date(Long.decode(aux)); } }
Es algo muy sencillo, pero si no lo has hecho nunca te puede retrasar un poco. ¿Habéis atacado servicios asmx desde Android alguna vez? ¿Habéis tenido algún otro problema?