Retrofit GSON serialize Date from json string into long or java.lang.Long
我正在使用Retrofit库进行REST调用。
传入的JSON看起来像这样。
1 2 3 | { "created_at":"2013-07-16T22:52:36Z", } |
如何告诉Retrofit或Gson将其转换为long?
您可以通过在改造实例上使用您自己的Gson对象设置自定义GsonConverter来轻松地做到这一点。在POJO中,您可以
1 2 3 4 5 6 7 8 | Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd'T'HH:mm:ssz") .create(); RestAdapter.Builder builder = new RestAdapter.Builder(); // Use a custom GSON converter builder.setConverter(new GsonConverter(gson)); ..... create retrofit service. |
您还可以通过在Retrofit
使用的gson实例上注册自定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Date.class, new DateTypeDeserializer()); public class DateTypeDeserializer implements JsonDeserializer<Date> { private static final String[] DATE_FORMATS = new String[]{ "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd", "EEE MMM dd HH:mm:ss z yyyy", "HH:mm:ss", "MM/dd/yyyy HH:mm:ss aaa", "yyyy-MM-dd'T'HH:mm:ss.SSSSSS", "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS", "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'", "MMM d',' yyyy H:mm:ss a" }; @Override public Date deserialize(JsonElement jsonElement, Type typeOF, JsonDeserializationContext context) throws JsonParseException { for (String format : DATE_FORMATS) { try { return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString()); } catch (ParseException e) { } } throw new JsonParseException("Unparseable date: "" + jsonElement.getAsString() +"". Supported formats: \ " + Arrays.toString(DATE_FORMATS)); } } |
在您的POJO中以字符串形式读取它,然后使用getter将其返回为long:
1 2 3 4 5 6 7 8 9 | String created_at; public long getCreatedAt(){ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); Date createDate = formatter.parse(created_at); return createDate.getTime(); } |
在这里可以引用SimpleDateFormat字符串
您可以简单地使用此
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class RestClient { private static final String BASE_URL ="your base url"; private ApiService apiService; public RestClient() { Gson gson = new GsonBuilder() .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'") .create(); RestAdapter restAdapter = new RestAdapter.Builder() .setLogLevel(RestAdapter.LogLevel.FULL) .setEndpoint(BASE_URL) .setConverter(new GsonConverter(gson)) .build(); apiService = restAdapter.create(ApiService.class); } public ApiService getApiService() { return apiService; } } |
阅读文档后,我尝试了此操作。它有效,但我不知道它是否会对其他类型有任何影响。
我的POJO需要很长的时间,因为保存到db时我不想转换。
我使用了自定义解串器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | JsonDeserializer<Long> deserializer = new JsonDeserializer<Long>() { @Override public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try{ if(json==null){ return new Long(0); } else{ String dateString = json.getAsString(); long dateLong = DateFormatUtil.getLongServerTime(dateString); return new Long(dateLong); } } catch(ParseException e){ return new Long(0); } } }; |
并使用它
1 2 3 4 5 | Gson gson = new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .setDateFormat(patternFromServer) .registerTypeAdapter(Long.class, deserializer) .create(); |
下面的代码已经过测试,并且经过大量的努力终于可以正常工作。
在创建改造对象之前,请创建Gson对象
1 2 3 4 |
,现在创建改造实例
1 2 3 4 | Retrofit retrofit = new Retrofit.Builder() .baseUrl("URL") .addConverterFactory(GsonConverterFactory.create(gson)) .build(); |
创建这两个类以序列化和反序列化日期格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | static class DateDeserializer implements JsonDeserializer<Date> { private final String TAG = DateDeserializer.class.getSimpleName(); @Override public Date deserialize(JsonElement element, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { String date = element.getAsString(); SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); formatter.setTimeZone(TimeZone.getTimeZone("GMT")); Date returnDate = null; try { returnDate = formatter.parse(date); } catch (ParseException e) { Log.e(TAG,"Date parser exception:", e); returnDate = null; } return returnDate; } } static class DateSerializer implements JsonSerializer<Date> { private final String TAG = DateSerializer.class.getSimpleName(); @Override public JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) { SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); formatter.setTimeZone(TimeZone.getDefault()); String dateFormatAsString = formatter.format(date); return new JsonPrimitive(dateFormatAsString); } } |
您应该通过
在
1 2 3 |
但是我可以建议您代替使用SimpleDateFormatter,而是从FasterXML / jackson-databind实现中查看该实现,以用于此类和该类中的ISO8601日期处理。这在很大程度上取决于您是否要解析很多日期。
还请注意,我们在Android应用程序(我们使用Java和Android库的组合)中使用SimpleDateFormatter时遇到了问题,在Java和Android中进行解析的结果不同。使用上述实现有助于解决此问题。
这是Java实现,这是Android实现,不是Java实现中
中缺少的
您可以在
setDateFormat()