最近在项目中遇到这么一个问题,我们后台需要向前端返回一个 json 数据,就是将一个地理位置对象以json的格式返回到前台,但是这个地理位置对象中的经纬度是Double数据类型,项目中规定,如果经纬度的值是double的默认值,那么返回0,而不是返回0.0,而我处理json一般使用的Gson来处理,如果简单的直接使用 new Gson().toJson(obj) 这种形式,那么是达不到我们想要的结果,因此我们需要自定义 Gson 的序列化来实现我们想要的结果,而 Gson 的TypeAdapter正好可以实现我们的功能。

TypeAdapter是 Gson 提供的用于某种类型的 序列化和反序列操作,并且它是强类型操作。比如TypeAdapter<Double>就只可以序列化和反序列操作Double这种类型,而不会对别的类型生效。TypeAdapter的使用需要注册到 Gson 的实例上。new GsonBuilder().registerTypeAdapter(类型,TypeAdapter实例).create();

需求:
    1、向前台返回一个地理位置的 json 数据,其中 经纬度是Double类型,如果Double的值是0时,页面上json的格式是 {key:0} 不可以是 {key:0.0}
    2、如果 Double 类型的数据值是 null,那么不向页面上返回。

实现:
    1、自定义一个 TypeAdapter 来处理 Double 类型的数据

一、定义一个地理位置 Location 对象
    @SerializedName 注解表示序列化后 json 的key 的是什么样的。

/**
* 地理位置
*
* @author huan.fu
* @date 2018/8/15 - 10:50
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Location {
/**
* 纬度
*/
@SerializedName("longitude")
private Double lat;
/**
* 经度
*/
private Double lng;
/**
* 详细地址
*/
@SerializedName("detail_address")
private String detailAddress;
}

二、定义一个 TypeAdapter,用来处理 Double 类型的数据

/**
* 序列化和反序列化 Double 类型的数据
*
* @author huan.fu
* @date 2018/8/15 - 11:26
*/
public class DoubleTypeAdapter extends TypeAdapter<Double> {
/**
* 序列化操作
*
* @param out
* @param value
* @throws IOException
*/
@Override
public void write(JsonWriter out, Double value) throws IOException {
// 如果 value 没有值,那么不进行序列化
if (null == value) {
out.nullValue();
// 如果 value 的值为 0,那么输出0,不输出默认的 0.0
} else if (value.equals(0D)) {
out.value(0);
// 否则直接输出
} else {
out.value(value);
}
}
/**
* 反序列操作
*
* @param in
* @return
* @throws IOException
*/
@Override
public Double read(JsonReader in) throws IOException {
return null;
}
}

三、测试代码

       注意:TypeApapter 的使用,需要先进行注册,否则不生效。

/**
* 测试 gson 的 double 处理
*
* @author huan.fu
* @date 2018/8/15 - 10:53
*/
public class GsonTest { @Test
public void doubleGsonAdapterTest() {
Location location = Location.builder()
.lat(0D)
.lng(1.1D)
.detailAddress(null)
.build(); // 不使用 adapter 处理 double
System.out.println(new Gson().toJson(location));
System.out.println("=========================");
// 使用 adapter 处理 double
Gson gson = new GsonBuilder()
.registerTypeAdapter(Double.class, new DoubleTypeAdapter())
.create();
System.out.println(gson.toJson(location));
}
}

四、结果

gson中TypeAdapter实现自定义序列化操作的更多相关文章

  1. Python json.dumps 特殊数据类型的自定义序列化操作

    场景描述: Python标准库中的json模块,集成了将数据序列化处理的功能:在使用json.dumps()方法序列化数据时候,如果目标数据中存在datetime数据类型,执行操作时, 会抛出异常:T ...

  2. Python json.dumps 自定义序列化操作

    def login_ajax(request): if request.method == "GET": return render(request, 'login_ajax.ht ...

  3. c# 通过json.net中的JsonConverter进行自定义序列化与反序列化

    https://www.cnblogs.com/yijiayi/p/10051284.html 相信大家在工作中会经常遇见对json进行序列化与反序列化吧,但通常的序列化与反序列化中的json结构与c ...

  4. Hive中自定义序列化器(带编码)

    hive SerDe的简介 https://www.jianshu.com/p/afee9acba686 问题 数据文件为文本文件,每一行为固定格式,每一列的长度都是定长或是有限制范围,考虑采用hiv ...

  5. mpi中利用自定义归约操作实现merge

    在归并排序中,很重要的一步是将两个排序数组合并成一个数组,这个操作叫merge.merge操作可以用来解决某些Top K问题. 问题描述 在哼唱搜索中,用户通过哼唱一个音乐片段去搜索与其相似的音乐.后 ...

  6. .Net Core 自定义序列化格式

    序列化对大家来说应该都不陌生,特别是现在大量使用WEBAPI,JSON满天飞,序列化操作应该经常出现在我们的代码上. 而我们最常用的序列化工具应该就是Newtonsoft.Json,当然你用其它工具类 ...

  7. Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  8. 基础命名空间:序列化_自定义序列化 System.Runtime.Serialization

    (  (From Msdn) 自定义序列化是控制类型的序列化和反序列化的过程,通过控制序列化,可以确保序列化兼容性.换而言之,在不中断类型核心功能的情况下,可在类型的不同版本之间序列化和反序列化. 重 ...

  9. Java Serializable接口(序列化)理解及自定义序列化

      1 Serializable接口 (1)简单地说,就是可以将一个对象(标志对象的类型)及其状态转换为字节码,保存起来(可以保存在数据库,内存,文件等),然后可以在适当的时候再将其状态恢复(也就是反 ...

随机推荐

  1. IKEv2协议协商流程: (IKE-SA-INIT 交换)第二包

    IKEv2协议协商流程: (IKE-SA-INIT 交换)第二包 文章目录 IKEv2协议协商流程: (IKE-SA-INIT 交换)第二包 1. IKEv2 协商总体框架 2. 第二包流程图 3. ...

  2. 使用python快速搭建http服务

    python2语法:python -m SimpleHTTPServer python3语法:python -m http.server 在局域网中使用web去访问http:/IP:8000即可 可以 ...

  3. grep、cut、awk、sed的使用

    grep.cut.awk.sed 常常应用在查找日志.数据.输出结果等等,并对我们想要的数据进行提取.通常grep,sed命令是对行进行提取,cut跟awk是对列进行提取 处理海量数据之grep命令 ...

  4. 集合Collection ----Set集合

    set系列集合:添加的元素是 无序,不重复,无索引的 ----HashSet: 无序,不重复,无索引 ------LinkHashSet<>:有序不重复无索引(添加顺序) ----Tree ...

  5. symfony中使用__construct获取services对象

    symfony中服务的使用总所周知的方便,但是当一个controller多次使用到同一个服务的时候就会出现在每个Action中都get获取服务,此时为了省事相信你也尝试使用构造函数申明一个私有对象避免 ...

  6. Java基础系列(6)- 注释

    注释 平时我们编写代码,在代码量比较少的时候,我们还可以看懂自己写的,但是当项目结构一旦复杂起来,我们就需要用到注释了 注释不会被执行,是给开发人员看的 书写注释是一个非常好的习惯 Java中的注释有 ...

  7. Linux文件(夹)属性与权限

    文件属性与权限,文件权限设置 参考资料:鸟哥的Linux私房菜 用户与用户组 Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这 ...

  8. Fiddler修改抓包请求

    hi,说到fiddler的用途,第一时间想到抓包,不过还有一个功能是:支持修改请求. 那么问题来了,怎么做呢?很简单,先定下我们需要修改哪个请求. 这里用F12跟fiddler做演示. 首先我们在F1 ...

  9. spring Data Jpa的依赖+配置

    spring data jpa 是spring基于的orm框架,jpa规范的基础上封装的一套JPA应用框架 添加的相关依赖: <properties> <spring.version ...

  10. 鸿蒙内核源码分析(进程镜像篇)|ELF是如何被加载运行的? | 百篇博客分析OpenHarmony源码 | v56.01

    百篇博客系列篇.本篇为: v56.xx 鸿蒙内核源码分析(进程映像篇) | ELF是如何被加载运行的? | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应 ...