Gson如何自定義Calendar序列化/反序列化 去fastjson筆記
阿新 • • 發佈:2022-04-21
直接開幹吧,假設有這麼一個類:
@Data @AllArgsConstructor class BeanSample { public Calendar birthday; @Override public String toString() { if (birthday == null) { return "birthday:null"; } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");return sdf.format(birthday.getTime()); } }
預設情況下,Gson序列化出來的結果很難看:
Gson gson = new Gson(); BeanSample bean = new BeanSample(Calendar.getInstance()); System.out.println(gson.toJson(bean));
輸出:
{"birthday":{"year":2022,"month":3,"dayOfMonth":20,"hourOfDay":21,"minute":18,"second":13}}
以我多年的搬磚經驗,加個TypeAdapter應該就可以了吧:
Gson gson = new GsonBuilder().registerTypeAdapter(Calendar.class, new TypeAdapter<Calendar>() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @Override public void write(JsonWriter out, Calendar value) throws IOException { if (value == null) { out.nullValue(); } else { out.value(sdf.format(value.getTime())); } } @Override public Calendar read(JsonReader in) throws IOException { //這是從json字串反序列化的,先不管 return null; } }).create(); BeanSample bean = new BeanSample(Calendar.getInstance()); System.out.println(gson.toJson(bean));
執行一下,居然沒生效,還是剛才的格式!於是,下個斷點:
發現birthday最終例項化後,型別是 GregorianCalendar(即:抽象類Calendar的子類),然後把剛才的程式碼略改了下:
Gson gson = new GsonBuilder().registerTypeAdapter(GregorianCalendar.class, new TypeAdapter<GregorianCalendar>() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @Override public void write(JsonWriter out, GregorianCalendar value) throws IOException { if (value == null) { out.nullValue(); } else { out.value(sdf.format(value.getTime())); } } @Override public GregorianCalendar read(JsonReader in) throws IOException { JsonToken token = in.peek(); switch (token) { case NUMBER: Date d = new Date(in.nextLong()); GregorianCalendar c = new GregorianCalendar(); c.setTime(d); return c; case STRING: String s = in.nextString(); try { Date parse = sdf.parse(s); GregorianCalendar instance = new GregorianCalendar(); instance.setTime(parse); return instance; } catch (ParseException e) { e.printStackTrace(); return null; } case NULL: default: return null; } } }).create(); BeanSample bean = new BeanSample(new GregorianCalendar()); //序列化 String json = gson.toJson(bean); System.out.println(json); //反序列化 System.out.println(gson.fromJson(json, BeanSample.class)); System.out.println("--------"); //換成時間戳格式 json = "{\"birthday\":" + System.currentTimeMillis() + "}"; System.out.println(json); System.out.println(gson.fromJson(json, BeanSample.class));
輸出:
{"birthday":"2022-04-20 22:27:08.864"} 2022-04-20 22:27:08.864 -------- {"birthday":1650464828881} 2022-04-20 22:27:08.881
這樣看起來好多了,而且json反序列化時,時間戳long型數字也一併做了相容
注:gson的其它小技巧,可參考先前寫的文章 去fastjson筆記