改造GSON将date从jsonstring序列化为java.util.date

我正在使用Retrofit库进行REST调用。 大部分我所做的一直是顺利的黄油,但由于某种原因,我有问题将JSON时间戳string转换为java.util.Date对象。 即将到来的JSON看起来像这样。

 { "date": "2013-07-16", "created_at": "2013-07-16T22:52:36Z", } 

我如何告诉Retrofit或Gson将这些string转换为java.util.Date objects

 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(gson)) .build(); 

你可以设置你自定义的Gsonparsing器进行翻新。 更多这里: 改造网站

看看Ondreju的反应,看看如何在改造2中实现这一点

@ gderaco的答案更新到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(); 

我是这样做的:

创buildDateTime类扩展date,然后写一个自定义的反序列化器:

 public class DateTime extends java.util.Date { public DateTime(long readLong) { super(readLong); } public DateTime(Date date) { super(date.getTime()); } } 

现在我们注册Date和DateTime转换器的解串器部分:

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

当您创buildRestAdapter时,请执行以下操作:

 new RestAdapter.Builder().setConverter(gsonWithDate()); 

你的Foo应该看起来像这样:

 class Foo { Date date; DateTime created_at; } 

Gson只能处理一种date时间格式(在生成器中指定的格式)加上iso8601,如果用自定义格式parsing是不可能的。 所以,一个解决scheme可以写你的自定义解串器。 为了解决你的问题,我定义了:

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

最后一步是用正确的适配器创build一个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] 

毫不夸张地说,如果您在创build的类中已经有一个名为“created_at”的Date对象,那么这很简单:

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