前言
谷歌的Gson库越来越流行,大多开发者也正转向Gson开发。spring官方底层默认支持jackson,但随着gson的流行,spring已经对Gson提供了支持,但对于日期的处理,jackson有@JsonFormatter注解提供方便,Gson默认却没有,就需要我们手动设置
一、项目背景
该实例基于spring+springmvc+mybatis框架和Gson框架
二、使用步骤
1.引入依赖
代码如下(示例):
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
2.默认Gson无法对日期进行格式化的原因
spring默认对gson实现仅单单new Gson(),并没有提供任何设置的方法,看其源码
3.解决办法
虽然没有提供默认设置方法,但提供了我们自己new Gson()的权力
因此我们可以继承此类,在构造方法中赋值
package com.lhy21.converter;
import com.google.gson.GsonBuilder;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
/**
* @Author xpdxz
* @ClassName MyGsonConverter
* @Description TODO
* @Date 2021/5/17 17:04
* @Version 1.0
*/
public class MyGsonConverter extends GsonHttpMessageConverter {
public MyGsonConverter() {
super.setGson(new GsonBuilder().setDateFormat("yyyy-M-dd").serializeNulls().create());
}
}
之后再spring-mvc中配置
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="com.lhy21.converter.MyGsonConverter">
<property name="supportedMediaTypes">
<list>
<value>text/json;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
测试,成功!
但其还存在一个问题,它属于全局gson对象,如果一个项目中有多种日期格式,那么这一个显然不够处理。
4.多种日期格式下的gson处理
jackson下有@JsonFormatter()注解,可以指定格式,非常方便。其实Gson也提供了@JsonAdapter注解,只是使用略有麻烦。
第一步:继承gson提供的TypeAdapter<这里写你自己要转换的日期类,例如TimeStamp>
第二步:重写方法,几乎模板式,只需修改自己所需的格式
package com.lhy21.adapter;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
/**
* @Author xpdxz
* @ClassName VisitedAdapter
* @Description TODO
* @Date 2021/5/22 10:38
* @Version 1.0
*/
public class VisitedAdapter extends TypeAdapter<Timestamp> {
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void write(JsonWriter out, Timestamp value) throws IOException {
out.value(simpleDateFormat.format(value));
}
@Override
public Timestamp read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
} else {
Timestamp date = this.deserializeToDate(in.nextString());
return date;
}
}
private Timestamp deserializeToDate(String s) {
synchronized (simpleDateFormat) {
return Timestamp.valueOf(s);
}
}
}
之后,在自己所需要转换的日期属性加入
即可