介绍:
Gson是google开发的一个Java对象与JSON相互转化的工具包.它轻巧简便,易于使用,有很完备的文档可供查询,并且是开源的。
一般用法:
下面,我们在这里示例一下gson的常用方式:先写一个用户类,如下:

package com.my.test; import java.io.Serializable; /** * 用户类 * @author qingfeng * */ public class User implements Serializable { /** * ID */ private int id; /** * 名字 */ private String name; /** * 类别 */ private Type type; /** * 默认构造方法 */ public User() {} /** * 构造方法 * @param id * @param name * @param type */ public User(int id, String name, Type type) { super(); this.id = id; this.name = name; this.type = type; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Type getType() { return type; } public void setType(Type type) { this.type = type; } }
再写一个用户类别类,如下:

package com.my.test; import java.io.Serializable; /** * 用户类别 * @author qingfeng * */ public class Type implements Serializable { /** * ID */ private int id; /** * 类别名称 */ private String name; /** * 默认构造方法 */ public Type() {} /** * 构造方法 * @param id * @param name */ public Type(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
现在,我们写一个示例类,演示gson的一般用户法,代码如下:

package com.my.test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; /** * 对象转换成json * @author qingfeng */ public class Object2Json { public static void main(String[] args) { //list示例 List2Json(); //map示例 Map2Json(); //复杂list示例 ComplexList2Json(); //复杂map示例 ComplexMap2Json(); } /** * 简单list集合转换json数组 */ public static void List2Json() { //创建一个list List<Type> list = new ArrayList<Type>(); for(int i = 0; i < 5; i ++) { list.add(new Type(i, "类别" + i)); } //创建一个gson对象 Gson gson = new Gson(); //转换成json String json = gson.toJson(list); //输出结果 System.out.println(json); } /** * 简单map转换成json */ public static void Map2Json() { //创建一个map Map<String, Type> map = new HashMap<String, Type>(); for(int i = 0; i < 5; i ++) { map.put("编号" + i, new Type(i, "类别" + i)); } //创建一个gson对象 Gson gson = new Gson(); //转换成json String json = gson.toJson(map); //输出结果 System.out.println(json); } /** * 复杂list转换成json */ public static void ComplexList2Json() { //创建一个list List<User> list = new ArrayList<User>(); //创建几个用户类别 Type t1 = new Type(1, "老师"); Type t2 = new Type(2, "学生"); //创建几个用户 User u1 = new User(1, "张三", t1); User u2 = new User(2, "李四", t1); User u3 = new User(3, "王五", t2); //将用户添加到list list.add(u1); list.add(u2); list.add(u3); //先创建一个gson对象 Gson gson = new Gson(); //将list转换成json String json = gson.toJson(list); //将结果输出 System.out.println(json); } /** * 复杂map转换成json */ public static void ComplexMap2Json() { //创建一个map Map<String, User> map = new HashMap<String, User>(); //创建几个用户类别 Type t1 = new Type(1, "老师"); Type t2 = new Type(2, "学生"); //创建几个用户 User u1 = new User(1, "张三", t1); User u2 = new User(2, "李四", t1); User u3 = new User(3, "王五", t2); //将用户添加到map map.put(u1.getName(), u1); map.put(u2.getName(), u2); map.put(u3.getName(), u3); //这里的map的key已经设置了用户的name了 //我们希望它的value里面包含对应的type和id就行了,不需要name属性 //而它的type里面的name和id还是要的 //所以,我们要给gson对象设置过滤条件 //设置要输出的属性 final String regUser = "|type|id|"; final String regOther = "|id|name|"; //创建一个带过滤条件的gson对象 Gson gson = new GsonBuilder() .setExclusionStrategies(new ExclusionStrategy() { /** * 设置要过滤的属性 */ @Override public boolean shouldSkipField(FieldAttributes attr) { //我们只过滤User类的id属性,而Type类的id属性还是要输出的 boolean b = false; //如果当前属性所在的类是User的话,就使用regUser过滤 //否则就用regOther来过滤 if(attr.getDeclaringClass() == User.class) { b = regUser.contains("|" + attr.getName() + "|"); } else { b = regOther.contains("|" + attr.getName() + "|"); } //这里,如果返回true就表示此属性要过滤,否则就输出 return !b; } /** * 设置要过滤的类 */ @Override public boolean shouldSkipClass(Class<?> clazz) { //这里,如果返回true就表示此类要过滤,否则就输出 return false; } }).create(); //转换成json String json = gson.toJson(map); //将结果输出 System.out.println(json); } }
常用技巧:
1、使用注解(SerializeName、Since等)设置过滤属性、设置属性的输出名称等信息;
2、使用Gson构造器定制自己的转换策略,如:用代码来设置属性的输出名称、设置要排除的属性(或者类)、为属性的值设置格式等等,这里就不一一缀述,总之,Gson构造器可以很灵活地将java对象转换成json对象。
常见问题:
1、如果要将泛型转换成json,如,一个Map是这样的,Map<String, Map<String, List<String>>> map,如果这样使用gson.toJson(map)得不到正确的结果的话,那么,我们可能要这样使用,gson.toJson(map,new TypeToken<Map<String, Map<String, List<String>>>>(){}.getType())。
2、信息不全,也就是说,同一个对象(假设所有属性都有值),转化后有的属性有值,有的属性没有值。
3、下级属性没有值。比如说,一个名为province的对象,它有一个叫做cities的属性,用来保存一个省份下面对应的所有市,用gson转换后,province的其他属性都有值,唯独cities没有。
4、其他类似的情况,这里就不一一列举了。
我没仔细看过gson包的源码,所以不清楚是什么地方导致了上述问题。
解决方案:
1、如果涉及到关联属性的对象,转换前可以先把它的关联属性转换并放入一个新建的Map或者List,然后按照层次结构重复这样的操作一层一层的往上转,这样,一般可以解决问题,但是,如果关联的层次比较深,做起来就很麻烦了。上面提到的问题3就可以用这种方式解决。
2、对用hibernate从数据库中取出的数据进行转换的时候,可能会遇到问题2,这就不好处理了,根据我的经历,这种情况一般是在多个地方都用hibernate读取数据库中的同一数据的时候发生的,下面是我常用的解决方法:
(1)尽可能地在一次请求中对某些数据(这个数据就是要转换的数据,或者它的关联属性包括了要转换的数据)只用hibernate查询一次,这样可能可以解决问题;
(2)如果上面提到的情况不可避免,那么,可以在这次请求中不取数据(要转换的),等请求完成后,在页面加载完成时以ajax的文式来请求,这样一般可以解决问题。
(3)如果以上方法都没有解决问题,可以根据API自定义转换策略,一般是可以解决这些问题的。
总结:
分析问题,不要死扣一个地方,要从多个方面分析,重新分析整个程序的执行过程,找出所有可能出现问题的地方,逐一验证,当然这不是一两句话能说清楚的,需要经验。
google gson学习
关键字: json gson java
Gson网址http://code.google.com/p/google-gson/
1.简单的处理list和map
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
Gson gson =
new
Gson();
List testList =
new
ArrayList();
testList.add(
"first"
);
testList.add(
"second"
);
String listToJson = gson.toJson(testList);
System.out.println(listToJson);
//prints ["first","second"]
Map testMap =
new
HashMap();
testMap.put(
"id"
,
"id.first"
);
testMap.put(
"name"
,
"name.second"
);
String mapToJson = gson.toJson(testMap);
System.out.println(mapToJson);
//prints {"id":"id.first","name":"name.second"}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
List<TestBean> testBeanList =
new
ArrayList<TestBean>();
TestBean testBean =
new
TestBean();
testBean.setId(
"id"
);
testBean.setName(
"name"
);
testBeanList.add(testBean);
java.lang.reflect.Type type =
new
com.google.gson.reflect.TypeToken<List<TestBean>>() {
}.getType();
String beanListToJson = gson.toJson(testBeanList,type);
System.out.println(beanListToJson);
//prints [{"id":"id","name":"name"}]
List<TestBean> testBeanListFromJson = gson.fromJson(beanListToJson, type);
System.out.println(testBeanListFromJson);
//prints [TestBean@1ea5671[id=id,name=name,birthday=<null>]]
|
map等其他集合类型同上
3.Date类型转化
先写工具类

2 2 .
3 3 . import com.google.gson.JsonDeserializationContext;
4 4 . import com.google.gson.JsonDeserializer;
5 5 . import com.google.gson.JsonElement;
6 6 . import com.google.gson.JsonParseException;
7 7 .
8 8 . public class UtilDateDeserializer implements JsonDeserializer < java.util.Date > {
9 9 .
10 10 . @Override
11 11 . public java.util.Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
12 12 . throws JsonParseException {
13 13 . return new java.util.Date(json.getAsJsonPrimitive().getAsLong());
14 14 . }
15 15 . }

2 2 .
3 3 . import com.google.gson.JsonElement;
4 4 . import com.google.gson.JsonPrimitive;
5 5 . import com.google.gson.JsonSerializationContext;
6 6 . import com.google.gson.JsonSerializer;
7 7 .
8 8 . public class UtilDateSerializer implements JsonSerializer < java.util.Date > {
9 9 .
10 10 . @Override
11 11 . public JsonElement serialize(java.util.Date src, Type typeOfSrc,
12 12 . JsonSerializationContext context) {
13 13 . return new JsonPrimitive(src.getTime());
14 14 . }
15 15 .
16 16 . }

2 2. * 序列化方法
3 3. * @param bean
4 4. * @param type
5 5. * @return
6 6. */
7 7 . public static String bean2json(Object bean, Type type) {
8 8 . Gson gson = new GsonBuilder().registerTypeAdapter(java.util.Date. class , new UtilDateSerializer())
9 9 . .setDateFormat(DateFormat.LONG).create();
10 10 . return gson.toJson(bean);
11 11 . }
12 12 .
13 13 . /**
14 14. * 反序列化方法
15 15. * @param json
16 16. * @param type
17 17. * @return
18 18. */
19 19 . public static < T > T json2bean(String json, Type type) {
20 20 . Gson gson = new GsonBuilder().registerTypeAdapter(java.util.Date. class , new UtilDateDeserializer())
21 21 . .setDateFormat(DateFormat.LONG).create();
22 22 . return gson.fromJson(json, type);
23 23 . }

2 # TestBean testBean = new TestBean();
3 # testBean.setId( " id " );
4 # testBean.setName( " name " );
5 # testBean.setBirthday( new java.util.Date());
6 # testBeanList.add(testBean);
7 #
8 # java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken < List < TestBean >> () {
9 # }.getType();
10 # String beanListToJson = bean2json(testBeanList, type);
11 # System.out.println( " beanListToJson: " + beanListToJson);
12 # // prints [{"id":"id","name":"name","birthday":1256531559390}]
13 #
14 # List < TestBean > testBeanListFromJson = json2bean(beanListToJson, type);
15 # System.out.println(testBeanListFromJson);
16 # // prints [TestBean@77a7f9[id=id,name=name,birthday=Mon Oct 26 12:39:05 CST 2009]]