json是web应用中最常用的通讯格式,应用场景之多,json的序列化工具也炒鸡多,粗略测试下来,执行效率 gson > fastjson > jackson,这里以gson的2.8.5版本为例
使用Gson替换Jackson
Jackson一直是springframework默认的json库,从4.1开始,springframework支持通过配置GsonHttpMessageConverter的方式使用Gson
import com.google.gson.*;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import java.lang.reflect.Type;
/**
* @描述:
* @公司:
* @版本: 1.0.0
* @日期: 2019年08月21日 17:40
*/
@Configuration
public class GsonConfig {
@Bean
public Gson gson(){
return new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
.registerTypeAdapter(String.class,new SpringfoxJsonToGsonAdapter()).create();
}
@Bean
public HttpMessageConverters httpMessageConverters() {
GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();
gsonHttpMessageConverter.setGson(gson());
return new HttpMessageConverters(gsonHttpMessageConverter);
}
public class SpringfoxJsonToGsonAdapter implements JsonSerializer<String> {
@Override
public JsonElement serialize(String json, Type type, JsonSerializationContext jsonSerializationContext) {
return new JsonParser().parse(json);
}
}
}
可以自己定制时间日期的序列化格式
gson工具类转换
/**
* @描述:
* @公司:
* @版本: 1.0.0
* @日期: 2019年08月16日 08:59
*/
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.internal.$Gson$Types;
import com.google.gson.reflect.TypeToken;
import org.springframework.beans.BeanUtils;
public class GsonUtils {
//不用创建对象,直接使用Gson.就可以调用方法
private static Gson gson = null;
//判断gson对象是否存在了,不存在则创建对象
static {
if (gson == null) {
//gson = new Gson();
//当使用GsonBuilder方式时属性为空的时候输出来的json字符串是有键值key的,显示形式是"key":null,而直接new出来的就没有"key":null的
gson= new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
}
}
//无参的私有构造方法
private GsonUtils() {
}
/**
* 将对象转成json格式
*
* @param object
* @return String
*/
public static String GsonString(Object object) {
String gsonString = null;
if (gson != null) {
gsonString = gson.toJson(object);
}
return gsonString;
}
/**
* 将json转成特定的cls的对象
*
* @param gsonString
* @param cls
* @return
*/
public static <T> T GsonToBean(String gsonString, Class<T> cls) {
T t = null;
if (gson != null) {
//传入json对象和对象类型,将json转成对象
t = gson.fromJson(gsonString, cls);
}
return t;
}
/**
* json字符串转成list
*
* @param gsonString
* @param cls
* @return
*/
public static <T> List<T> GsonToList(String gsonString, Class<T> cls) {
List<T> list = null;
if (gson != null) {
Type type = $Gson$Types.newParameterizedTypeWithOwner(null, ArrayList.class, cls);
list = gson.fromJson(gsonString, type);
}
return list;
}
/**
* json字符串转成list中有map的
*
* @param gsonString
* @return
*/
public static <T> List<Map<String, T>> GsonToListMaps(String gsonString) {
List<Map<String, T>> list = null;
if (gson != null) {
list = gson.fromJson(gsonString,
new TypeToken<List<Map<String, T>>>() {
}.getType());
}
return list;
}
/**
* json字符串转成map的
*
* @param gsonString
* @return
*/
public static <T> Map<String, T> GsonToMaps(String gsonString) {
Map<String, T> map = null;
if (gson != null) {
map = gson.fromJson(gsonString, new TypeToken<Map<String, T>>() {
}.getType());
}
return map;
}
}
gson序列化总结
- gson在将json字符串序列化为list的bean的时候,用TypeToken的方式有bug,上面的示例代码,已经修复了这个bug
- gson在序列化的时候,可以给bean加注解,以实现一些功能
@SerializedName(value = "emailAddress", alternate = { "email", "email_address" })
private String emailAddress;
当上面的三个属性(email_address、email、emailAddress)中都出现,或出现任意一个时均可以得到正确的结果。
注:当多种情况同时出时,以最后一个出现的值为准。
- 自定义字段的名字
@SerializedName("w");
int width
这个注解可以用来自定义序列化和反序列化过程中字段的名字。
以上面为例,当序列化的时候,会把Java bean中的字段width存储成w,在反序列化的时候会把Json的w这个key反序列化到Java bean的width字段上
序列化扩展-两个实体类转换
- 用BeanUtils或者PropertyUtils的copyProperties,同名属性不同类型,PropertyUtils会报错
- Spring 中的BeanUtils与apache中的BeanUtils都可以用,但是推荐使用Spring,同名属性一个属性为日期类型,Spring会直接忽视,apache在做日期转换时会有问题,问题情况比较多,这里不做细分了
/**
* 实体类转字体类
* @param source 源实体类
* @param cls
* @return
*/
public static <T> T gsonBean2(Object source, Class<T> cls){
T t = null;
if (source !=null && gson != null) {
//创建泛型类的实例
try {
t=cls.newInstance();
BeanUtils.copyProperties(source,t);
} catch (Exception e) {
e.printStackTrace();
}
}
return t;
}
/**
* 实体类list转字体类list, List<?>是type-safe
* @param sourceList 源实体类
* @param cls
* @return
*/
public static <T> List<T> gsonBeanList2(List<?> sourceList, Class<T> cls){
List<T> list = null;
if (sourceList !=null && gson != null) {
list = new ArrayList<T>();
//创建泛型类的实例
try {
for(Object source : sourceList){
T t = cls.newInstance();
BeanUtils.copyProperties(source,t);
list.add(t);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}