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!完事了,重啟服務器查看效果