Gson异常强大因此使用它代替了Jackson作为SpringMVC消息转换器。
在自己的项目中,发现对象在序列化后,日期格式出现了问题。
先看问题
在员工表中有一列是生日,字段类型为Date,也就是只存储到年月日,不带小时分秒,见下图数据库中的数据
前台列表向后台请求数据,然后在页面显示,可以看到,日期后面带有了小时分秒,而对于生日来说,这是没有意义的。见下图
问题出现在哪?
问题就出现在了 spring 的 message-converters 上,在我的项目中,配置的类型转换器为 google的 gson。可以看到全局配置为“
yyyy-MM-dd HH:mm:ss:SSS” ,这是带有小时分秒的。所以当请求返回给浏览器的时候,spring会利用Gson将对象序列化输出到前端,按照配置的规则,就会带有小时分秒了。具体见下面的代码:
<!--开启 spring-mvc注解--> <mvc:annotation-driven> <!--设置JSON转换器为Gson--> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> <value>text/html;charset=UTF-8</value> </list> </property> </bean> <bean class="org.springframework.http.converter.json.GsonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> <property name="gson"> <bean class="org.springframework.http.converter.json.GsonFactoryBean"> <property name="serializeNulls" value="true"/> <property name="disableHtmlEscaping" value="true"/> <property name="dateFormatPattern" value="yyyy-MM-dd HH:mm:ss:SSS" /> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
如何解决呢?
两种办法:
1、修改全局设置,将上述的配置修改yyyy-MM-dd。这样做有一个弊端:所有的日期处理都会受到影响。
2、利用@JsonAdapter注解,在想要特殊处理的属性上,添加该注解。
重点介绍第二种方式
首先,在要处理的属性上增加注解
@JsonAdapter(DateAdapter.class) private Date birthday;
该注解接收一个参数,是类且继承TypeAdapter。要重写read(JsonReader in)、write(JsonWriter jsonWriter, Date date)这两个抽象方法。具体如下:
write是序列化、read是反序列化
package com.wt.common.core.adapter; import com.google.gson.JsonSyntaxException; import com.google.gson.TypeAdapter; import com.google.gson.internal.bind.util.ISO8601Utils; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; /** * @ProjectName: syInfo * @Package: com.wt.common.core.adapter * @Description: gson 日期适配器 * @Author: lichking2017@aliyun.com * @CreateDate: 2018/5/5 上午11:12 * @Version: v1.0 */ public class DateAdapter extends TypeAdapter<Date>{ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); @Override public void write(JsonWriter jsonWriter, Date date) throws IOException { jsonWriter.value(sdf.format(date)); } @Override public Date read(JsonReader in) throws IOException { if(in.peek() == JsonToken.NULL) { in.nextNull(); return null; } else { Date date = this.deserializeToDate(in.nextString()); return date; } } private Date deserializeToDate(String s) { synchronized (sdf) { try { return sdf.parse(s); } catch (ParseException ignored) {} try { return sdf.parse(s); } catch (ParseException ignored) {} try { return ISO8601Utils.parse(s, new ParsePosition(0)); } catch (ParseException e) { throw new JsonSyntaxException(s, e); } } } }
OK!完事了,重启服务器查看效果