前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gson如何自定义Calendar序列化/反序列化

Gson如何自定义Calendar序列化/反序列化

作者头像
菩提树下的杨过
发布2022-04-27 11:01:09
7870
发布2022-04-27 11:01:09
举报

直接开干吧,假设有这么一个类:

代码语言:javascript
复制
    @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序列化出来的结果很难看:

代码语言:javascript
复制
        Gson gson  = new Gson();
        BeanSample bean = new BeanSample(Calendar.getInstance());
        System.out.println(gson.toJson(bean));

输出:

代码语言:javascript
复制
{"birthday":{"year":2022,"month":3,"dayOfMonth":20,"hourOfDay":21,"minute":18,"second":13}}

以我多年的搬砖经验,加个TypeAdapter应该就可以了吧:

代码语言:javascript
复制
        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的子类),然后把刚才的代码略改了下:

代码语言:javascript
复制
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));

输出:

代码语言:javascript
复制
{"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笔记

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-04-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档