SpringMVC+GSON 對象序列化--日期格式的處理


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM