Gson的自定义序列化的方法

今天做项目的时候,碰到个需求,需要对时间做格式化,Gson提供的dateFormat方法,但是那个只是统一的格式化时间,我这次的序列化有点特殊,有些时间格式的没有时分秒的,但是有些时间格式又十分精确必须要求时分秒。但是在pojo里面的对象全部都是date类型...于是查询Gson的API看能否找到自定义序列化方式的方法。

在查询了部分API和google是开发文档之后,找到了部分类似相关的描述:

Sometimes default representation is not what you want. This is often the case when dealing with library classes (DateTime, etc). 
Gson allows you to register your own custom serializers and deserializers. This is done by defining two parts: 
Json Serialiers: Need to define custom serialization for an object
Json Deserializers: Needed to define custom deserialization for a type
Instance Creators: Not needed if no-args constructor is available or a deserializer is registered
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(MyType2.class, new MyTypeAdapter());
gson.registerTypeAdapter(MyType.class, new MySerializer());
gson.registerTypeAdapter(MyType.class, new MyDeserializer());
gson.registerTypeAdapter(MyType.class, new MyInstanceCreator());

registerTypeAdapter call checks if the type adapter implements more than one of these interfaces and register it for all of them.
Writing a Serializer

Here is an example of how to write a custom serializer for JodaTime DateTime class. 

private class DateTimeSerializer implements JsonSerializer<DateTime> {
  public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) {
    return new JsonPrimitive(src.toString());
  }
}

Gson calls toJson() when it runs into a DateTime object during serialization.
Writing a Deserializer

Here is an example of how to write a custom deserializer for JodaTime DateTime class. 

private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
  public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    return new DateTime(json.getAsJsonPrimitive().getAsString());
  }
}

Gson calls fromJson() when it needs to deserialize a JSON string fragment into a DateTime object

上面也给出了示例,大概是意思是,Gson支持定义对指定的类型来做个性化的序列化,大体就是Gson里面有个registerTypeAdapter方法,照着用就可以了。API详细描述我也就不在铺上去了,有兴趣的自己去查。

根据上面的意思,我大概完善了下我的格式化方法:

	/**
	 * @author yohoph
	 * @date Apr 25, 2013
	 * @param obj
	 * @return
	 * @Description 序列化字符串的时候带时间格式
	 */
	public static String parseJsonSetDate(Object obj){
		GsonBuilder builder = new GsonBuilder();
		builder.excludeFieldsWithoutExposeAnnotation();//不转换没有@Expose注解的字段
		builder.setExclusionStrategies(new ExcuUserBox());
		builder.setDateFormat("yyyy-MM-dd");
		builder.registerTypeAdapter(Timestamp.class, new JsonSerializer<Timestamp>(){//Timestamp时间格式需要带时分秒
			@Override
			public JsonElement serialize(Timestamp date, Type type,
					JsonSerializationContext arg2) {
					return new JsonPrimitive(DateUtil.getDate(date));</span>
			}});
		Gson gson = builder.create();
		return gson.toJson(obj);
	}


DateUtil.java方法:

        private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	/**
	 * @author admin
	 * @date 2011年4月21日
	 * @param date 时间
	 * @return
	 * @Description 格式化一个时间,以默认的yyyy-MM-dd hh:mm:ss 格式
	 */
	public static String getDate(Date date){
		return dateFormat.format(date);
	}


这地方有几点我需要说明下:

1.class类型必须使用详细的实体类类型,不能用父类类型引用来代替,这里面由于java的数据库存在,里面现在有三个类型java.util.Date,java.sql.Date,java.sql.Timestamp这几个类型存在,直接使用java.util.Date.class的类型方法,在hibernate映射的时候,Gson是不认这三者的区别的。也不知道Gson的setDateFormat方法是如何对这些类型做统一处理的,由于翻墙十分痛苦,Gson的源码很不好下载。一直没能看到Gson的源码。也没法去讨论这里其中的存在

2.我最初的时候本是打算java.util.Date,java.sql.Date,java.sql.Timestamp三个一样做一个的,后来考虑了下,应该是可以跟setDateFormat兼容的,估计Gson里面这个registerTypeAdpter的方法优先级很高。所以才能做到,详细的估计得去看源码才能知道了。

2.返回值类型,必须得是JsonPrimitive,虽然重写规范里面只要你返回JsonElement就行了,但是JsonObject,JsonArray这两个对象是不能进参数里面去的,你们可以注意下。当然如果你们定义的是一个对象甚至是一个集合。就另谈了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值