[Gson六]Gson类型适配器(TypeAdapter)

编程技术  /  houtizong 发布于 3年前   244

TypeAdapter的使用动机

 Gson在序列化和反序列化时,默认情况下,是按照POJO类的字段属性名和JSON串键进行一一映射匹配,然后把JSON串的键对应的值转换成POJO相同字段对应的值,反之亦然,在这个过程中有一个JSON串Key对应的Value和对象之间如何转换(序列化/反序列化)的问题。

 

以Date为例,在序列化和反序列化时,Gson默认使用java.text.DateFormat将Date对象进行序列化成日期字符串, 以及将日期字符串反序列化为Date对象。

 

这种默认的转换逻辑,大多数情况下能够满足需求,不过有时我们需要自定义这个转换的逻辑,比如在JSON串中定义的是日期的毫秒数,而POJO中定义的是Date类型,为了适配这种类型(字串符数字和Date)的转换,Gson提供了类型适配器。通过类型适配器这种扩展机制,Gson的使用者可以根据实际的需要对某个具体类型的序列化和反序列化的转换进行控制

 

 Date和字符串日期毫秒数适配

将日期类型序列化和反序列化长整数字符串(串中以长整数毫秒数表示日期)

 

import com.google.gson.Gson;import com.google.gson.GsonBuilder;import com.google.gson.TypeAdapter;import com.google.gson.stream.JsonReader;import com.google.gson.stream.JsonWriter;import java.io.IOException;import java.util.Date;class LongDateTypeAdapter extends TypeAdapter<Date> {    @Override    public void write(JsonWriter out, Date value) throws IOException {        if (value == null) {            out.nullValue();        } else {            out.value(value.getTime());        }    }    @Override    public Date read(JsonReader in) throws IOException {        if (in.peek() == null) {            return null;        }        String str = in. nextString();        Date d  = new Date(Long.parseLong(str));        return d;    }}class Model {    private Date date;    public Date getDate() {        return date;    }    public void setDate(Date date) {        this.date = date;    }}public class Test {    public static void main(String[] args) {        Date d = new Date();        Model m = new Model();        m.setDate(d);        Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new LongDateTypeAdapter()).create();        String str = gson.toJson(m);        System.out.println(str); //{"date":1407921708088}        m = gson.fromJson(str, Model.class);        System.out.println(m.getDate().getTime()); //1407921708088    }}

 

 上例中,将Model对象序列化为{"date":1407921708088},然后把{"date":1407921708088}反序列化为Model对象,Gson通过自定义的类型适配器LongDateTypeAdapter将日期类型Date和Long进行了适配。

数字和Enum类型的适配

import com.google.gson.Gson;import com.google.gson.GsonBuilder;import com.google.gson.TypeAdapter;import com.google.gson.stream.JsonReader;import com.google.gson.stream.JsonToken;import com.google.gson.stream.JsonWriter;import java.io.IOException;enum Status {    OK, ERROR, UNKNOWN;}class EnumTypeAdapter extends TypeAdapter<Status> {    @Override    public Status read(JsonReader in) throws IOException {        if (in.peek() == JsonToken.NULL) {            return null;        } else {            int status = in.nextInt();            if (status == 0) {                return Status.OK;            } else if (status == 1) {                return Status.ERROR;            } else {                return Status.UNKNOWN;            }        }    }    @Override    public void write(JsonWriter out, Status value) throws IOException {        if (value == null) {            out.nullValue();        } else if (value == Status.OK) {            out.value(0);        } else if (value == Status.ERROR) {            out.value(1);        } else {            out.value(2);        }    }}public class Test {    public static void main(String[] args) {        Gson gson = new GsonBuilder().registerTypeAdapter(Status.class, new EnumTypeAdapter()).create();        String str = gson.toJson(Status.OK);        System.out.println(str);//0        Status status = gson.fromJson(str, Status.class);        System.out.println(status);//OK    }}
 

 

 Gson预定义适配器

 上面说到了,Gson默认使用java.text.DateFormat对日期和字符串进行转换,那么这种转换逻辑是如何实现的?这是使用了Gson预定义的适配器DateTypeAdapter, Gson预定义适配器在第七部分进行分析

 

 

 

 

 

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客