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));
	}
}

 

四、结果

 

posted @ 2018-08-15 11:45  huan1993  阅读(238)  评论(0编辑  收藏  举报