论坛首页 Java企业应用论坛

google-gson

浏览 10043 次
锁定老帖子 主题:google-gson
精华帖 (3) :: 良好帖 (0) :: 新手帖 (7) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-04-09   最后修改:2009-05-06
    /**
     * 
     * 将bean转换成json串,bean中可以包含自定义属性,<br>
     * 转换后的json串是有层次结构的<br>
     * Date类型的将被按字符串赋给json串<br>
     * <link>http://sites.google.com/site/gson/Home</link>
     * 
     * @param bean
     * @return json串
     */
    public static String bean2json(Object bean) {
        Gson gson = new GsonBuilder().registerTypeAdapter(java.sql.Date.class,
                new SQLDateSerializer()).setDateFormat(DateFormat.LONG)
                .create();
        return gson.toJson(bean);
    }


SQLDateSerializer.class

public class SQLDateSerializer implements JsonSerializer<java.sql.Date> {

    public JsonElement serialize(java.sql.Date src, Type typeOfSrc,
            JsonSerializationContext context) {
        return new JsonPrimitive(src.toString());
    }
}
   发表时间:2009-07-15   最后修改:2009-08-15
util.Date和sql.Date被转成长整形用于序列化传输

SQLDateSerializer.class
public class SQLDateSerializer implements JsonSerializer<java.sql.Date> {

	public JsonElement serialize(java.sql.Date src, Type typeOfSrc,
			JsonSerializationContext context) {
		return new JsonPrimitive(src.getTime());
	}
}


UtilDateSerializer.class
public class UtilDateSerializer implements JsonSerializer<java.util.Date> {

	public JsonElement serialize(java.util.Date src, Type typeOfSrc,
			JsonSerializationContext context) {
		return new JsonPrimitive(src.getTime());
	}
}


序列化方法
public static String bean2json(Object bean) {
		Gson gson = new GsonBuilder().registerTypeAdapter(java.sql.Date.class,
				new SQLDateSerializer()).registerTypeAdapter(
				java.util.Date.class, new UtilDateSerializer()).setDateFormat(
				DateFormat.LONG).create();
		return gson.toJson(bean);
	}


序列化后如下
{"name":"改过","dob":1247626770406,"inTime":1247626770406}


序列化反序列化类Worker.class
	private String name;

	private java.sql.Date dob;

	private java.util.Date inTime;
0 请登录后投票
   发表时间:2009-08-15   最后修改:2009-08-18
序列化反序列化类Factory.class
	private String name;

	private Worker worker;

	private Set<Worker> workers;

	private List<Worker> lws;


UtilDateDeserializer.class
public class UtilDateDeserializer implements JsonDeserializer<java.util.Date> {

	public java.util.Date deserialize(JsonElement json, Type typeOfT,
			JsonDeserializationContext context) throws JsonParseException {
		return new java.util.Date(json.getAsJsonPrimitive().getAsLong());
	}
}


SQLDateDeserializer.class
public class SQLDateDeserializer implements JsonDeserializer<java.sql.Date> {

	public java.sql.Date deserialize(JsonElement json, Type typeOfT,
			JsonDeserializationContext context) throws JsonParseException {
		return new java.sql.Date(json.getAsJsonPrimitive().getAsLong());
	}
}


反序列化方法
	public static <T> T json2bean(String json, Type type) {
		Gson gson = new GsonBuilder().registerTypeAdapter(java.sql.Date.class,
				new SQLDateDeserializer()).registerTypeAdapter(
				java.util.Date.class, new UtilDateDeserializer())
				.setDateFormat(DateFormat.LONG).create();
		return gson.fromJson(json, type);
	}


测试代码
	private Worker worker;
	private Factory factory;

	@Before
	public void setUp() {
		worker = new Worker();
		worker.setName("你想");
		worker.setDob(new java.sql.Date(Calendar.getInstance()
				.getTimeInMillis()));
		worker.setInTime(Calendar.getInstance().getTime());

		Worker w2 = new Worker();
		w2.setName("改过");
		w2.setDob(new java.sql.Date(Calendar.getInstance().getTimeInMillis()));
		w2.setInTime(Calendar.getInstance().getTime());

		Worker w3 = new Worker();
		w3.setName("古古怪怪");
		w3.setDob(new java.sql.Date(Calendar.getInstance().getTimeInMillis()));
		w3.setInTime(Calendar.getInstance().getTime());

		List<Worker> lws = new ArrayList<Worker>();
		lws.add(worker);
		lws.add(w2);

		Set<Worker> sws = new HashSet<Worker>();
		sws.add(w3);
		sws.add(worker);
		sws.add(w2);

		factory = new Factory();
		factory.setName("IBM");
		factory.setWorker(worker);
		factory.setLws(lws);
		factory.setWorkers(sws);
	}

	@Test
	public void testSerializer() {

		String factoryJson = JsonUtils.bean2json(factory);

		P.rintln(factoryJson);

		Factory factoryCopy = (Factory) JsonUtils.json2bean(factoryJson,
				Factory.class);

		P.rintln(factoryCopy.getWorker().getInTime());
		P.rintln(JsonUtils.bean2json(worker));

		P.rintln(new java.sql.Date(1247625062171L));
		P.rintln(new java.util.Date(1247625621406L));

		String json = "{\"name\":\"改过\",\"dob\":1247626770406,\"inTime\":1247626770406}";
		Worker w4 = (Worker) JsonUtils.json2bean(json, Worker.class);
		P.rintln(w4.getName());
	}
0 请登录后投票
   发表时间:2009-08-18   最后修改:2009-08-18
关于泛型问题
序列化的时候很好处理

反序列化的时候,由于Java Type Erasure的原因
只能获得其raw type,这时候无法完成转换

以下是Gson User Guide原文:
Gson User Guide 写道
This works fine if the object is a non-generic type.
However, if the object is of a generic type,
then the Generic type information is lost because of Java Type Erasure.


我们需要利用TypeToken来明确告诉gson我们所需的类型

	@Test
	public void testGenericType() {
		List<String> holder = new ArrayList<String>();
		holder.add("Hello Gson");
		String json = JsonUtils.bean2json(holder);
		P.rintln(json);
		Type type = new TypeToken<List<String>>() {
		}.getType();
		Object obj = JsonUtils.json2bean(json, type);
		P.rintln(obj);
		P.rintln(obj.getClass());
	}
0 请登录后投票
   发表时间:2009-12-23  
如果我从服务端传来一个bean Collection,而这时,我想做通用的json解析器,这时我并不知道collection中存的是什么类型的bean,请问这种情况下怎么反序列化bean Collection!!
0 请登录后投票
   发表时间:2010-01-14  
貌似 gson在Java对象和JSON对象互相转换的时候
并没有调用getter和setter 而是直接访问Java对象的属性
这就没给我们留下在中间干点什么的机会
怎么办呢?
0 请登录后投票
   发表时间:2010-03-19  
jessige_27 写道
貌似 gson在Java对象和JSON对象互相转换的时候
并没有调用getter和setter 而是直接访问Java对象的属性
这就没给我们留下在中间干点什么的机会
怎么办呢?


确实没调用
Hibernate  lazy='true' 的死活转成的 json 串都是空的
必须要在转之前调用任意 getter
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics