Gson的一些注意事项

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rocklee/article/details/89239586

    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数条街. 

猜你喜欢

转载自blog.csdn.net/rocklee/article/details/89239586