Gson与Jackson或fastjson不同的是, 它的序列/反序列化是用通过读取类的属性进行的,也就是说, 跟getter/setter没什么关系, 但要注意下面几点:
1/ 比如你要处理的类B继承自类A, 若A有一属性f1为Object , 而B则将f1定义为XX具体类型, 那么如果你不处理的话, gson会报错, 说存在两个相同的f1(话说为什么不能智能一点呢?), 这时候你要处理父类A中的f1, 比如加上下面的父类中的response:
public class JSONResponseBean implements Serializable{
private static final long serialVersionUID = 7524629476224449501L;
public int errCode;
public String errMessage;
public transient Object response;
public JSONResponseBean(){
}
}
然后构造GsonBuilder的时候将TRANSIENT的属性排外即可 (见后面的代码).
********13/Apr 更新***********
但如果遇到这个基类的response也必须要序列化的而且子类的同名又必须序列化的,又如何解决? 如我提问的贴子: https://bbs.csdn.net/topics/392566039
可以修改源代码ReflectiveTypeAdapterFactory.java的方法getBoundFields, 在String name = fieldNames.get(i);的后面加上if (result.containsKey(name))continue; //by rock 13/Apr/2019
这样, 想用基类时, Object response也可以序列化, 想用子类具体化的response也可以序列化.
*********END *****************
2/日期时间类的处理, 因为要避免日期格式/时区等问题, 即使是日期时间类型, 从服务器返回的依然是时间截(一串长长的数字), 那么这串数字如何变为java.util.Date? 这时候需要自定义转换适配器,如下, 然后在GsonBuilder中为Date类型注册这个转换适配器:
package com.freestyle.utils;
import java.lang.reflect.Type;
import java.util.Date;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
public class GsonDateTimeTypeAdapter implements JsonSerializer<Date>,
JsonDeserializer<Date> {
public GsonDateTimeTypeAdapter() {
}
@Override
public synchronized JsonElement serialize(Date date, Type type,
JsonSerializationContext jsonSerializationContext) {
synchronized (this) {
//String dateFormatAsString = dateFormat.format(date);
return new JsonPrimitive(date.getTime());
}
}
@Override
public synchronized Date deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) {
synchronized (this) {
//return dateFormat.parse(jsonElement.getAsString());
long lvDt=jsonElement.getAsLong();
return new Date(lvDt);
}
}
}
3/ 建立GsonBuilder和从builder中取得Gson对象, builder将一些final, transient等特性的属性field排除掉, 并将GsonDateTimeTypeAdapter注册为Date类型的转换适配器:
private static GsonBuilder builder;
static {
builder = new GsonBuilder();
builder.excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC,Modifier.PRIVATE,Modifier.PROTECTED);
builder.registerTypeAdapter(Date.class, new GsonDateTimeTypeAdapter());
}
public static Gson getGson(){
return builder.create();
}
今天初学Gson, 暂时笔记到此, 日后如有需要再继续添加. 可能有人会问, 你的jackson json用得好好的为什么要换gson, 还不是因为两个字:性能!!!
在对象结构复杂的记录众多并且设备配置很垃圾的情况下, gson可以甩jackson数条街.