gson中TypeAdapter实现自定义序列化操作
最近在项目中遇到这么一个问题,我们后台需要向前端返回一个 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)); } }
四、结果