Retrofit Gson сериализует дату из строки json в java.утиль.дата
Я использую библиотеку Retrofit для моих вызовов REST. Большая часть того, что я сделал, была гладкой, как масло, но по какой-то причине у меня возникли проблемы с преобразованием строк JSON timestamp в java.util.Date объекты. JSON, который входит, выглядит так.
{
"date": "2013-07-16",
"created_at": "2013-07-16T22:52:36Z",
}
как я могу сказать Retrofit или Gson, чтобы преобразовать эти строки в java.util.Date objects?
6 ответов:
Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd'T'HH:mm:ss") .create(); RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(API_BASE_URL) .setConverter(new GsonConverter.create(gson)) .build();вы можете настроить свой настроенный парсер Gson для дооснащения . Подробнее здесь: Модернизация Сайта
посмотрите на ответ Ondreju, чтобы увидеть, как реализовать это в retrofit 2
@gderaco обновлено для того чтобы Retrofit 2.0:
Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd'T'HH:mm:ss") .create(); Retrofit retrofitAdapter = new Retrofit.Builder() .baseUrl(API_BASE_URL) .addConverterFactory(GsonConverterFactory.create(gson)) .build();
вот как я сделал это:
создайте класс DateTime, расширяющий дату, а затем напишите пользовательский десериализатор:
public class DateTime extends java.util.Date { public DateTime(long readLong) { super(readLong); } public DateTime(Date date) { super(date.getTime()); } }теперь для части десериализатора, где мы регистрируем конвертеры даты и времени:
public static Gson gsonWithDate(){ final GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { final DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); @Override public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try { return df.parse(json.getAsString()); } catch (final java.text.ParseException e) { e.printStackTrace(); return null; } } }); builder.registerTypeAdapter(DateTime.class, new JsonDeserializer<DateTime>() { final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try { return new DateTime(df.parse(json.getAsString())); } catch (final java.text.ParseException e) { e.printStackTrace(); return null; } } }); return builder.create(); }и когда вы создаете свой RestAdapter, выполните следующие действия:
new RestAdapter.Builder().setConverter(gsonWithDate());ваш Foo должен выглядеть так:
class Foo { Date date; DateTime created_at; }
Gson может обрабатывать только один формат datetime (указанные в builder) плюс iso8601, если разбор с пользовательским форматом невозможен. Таким образом, можно написать пользовательский десериализатор. Чтобы решить вашу проблему я определил:
package stackoverflow.questions.q18473011; import java.util.Date; public class Foo { Date date; Date created_at; public Foo(Date date, Date created_at){ this.date = date; this.created_at = created_at; } @Override public String toString() { return "Foo [date=" + date + ", created_at=" + created_at + "]"; } }С этим десериализатор:
package stackoverflow.questions.q18473011; import java.lang.reflect.Type; import java.text.*; import java.util.Date; import com.google.gson.*; public class FooDeserializer implements JsonDeserializer<Foo> { public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String a = json.getAsJsonObject().get("date").getAsString(); String b = json.getAsJsonObject().get("created_at").getAsString(); SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdfDateWithTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); Date date, created; try { date = sdfDate.parse(a); created = sdfDateWithTime.parse(b); } catch (ParseException e) { throw new RuntimeException(e); } return new Foo(date, created); } }последний шаг-создать
Gsonэкземпляр с подходящим адаптером:package stackoverflow.questions.q18473011; import com.google.gson.*; public class Question { /** * @param args */ public static void main(String[] args) { String s = "{ \"date\": \"2013-07-16\", \"created_at\": \"2013-07-16T22:52:36Z\"}"; GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Foo.class, new FooDeserializer()); Gson gson = builder.create(); Foo myObject = gson.fromJson(s, Foo.class); System.out.println("Result: "+myObject); } }мой результат:
Result: Foo [date=Tue Jul 16 00:00:00 CEST 2013, created_at=Tue Jul 16 22:52:36 CEST 2013]
буквально если у вас уже есть объект даты с именем "created_at" в классе, который вы создаете, то это так просто:
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").create(); YourObject parsedObject1 = gson.fromJson(JsonStringYouGotSomehow, YourObject.class);и вы сделали. не требуется сложное переопределение.
вы можете определить два новых класса, как этот:
import java.util.Date; public class MyDate extends Date { }и
import java.util.Date; public class CreatedAtDate extends Date { }ваш POJO будет выглядеть так:
import MyDate; import CreatedAtDate; public class Foo { MyDate date; CreatedAtDate created_at; }наконец-то установите свой собственный десериализатор:
public class MyDateDeserializer implements JsonDeserializer<Date> { public static final SimpleDateFormat sServerDateDateFormat = new SimpleDateFormat("yyyy-MM-dd"); @Override public MyDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if (json != null) { final String jsonString = json.getAsString(); try { return (MyDate) sServerDateDateFormat.parse(jsonString); } catch (ParseException e) { e.printStackTrace(); } } return null; } }и
GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(MyDate.class, new MyDateDeserializer());
Comments