关于Gson的一般用法及常见问题的解决方案

来源:互联网 发布:看电影翻译软件 编辑:程序博客网 时间:2024/05/17 23:41

介绍:

  Gson是google开发的一个Java对象与JSON相互转化的工具包.它轻巧简便,易于使用,有很完备的文档可供查询,并且是开源的。

 

一般用法:

  下面,我们在这里示例一下gson的常用方式:先写一个用户类,如下:

[java] view plaincopyprint?
  1.    
  2.   
  3. package com.my.test;  
  4.   
  5. import java.io.Serializable;  
  6.   
  7. /** 
  8.  * 用户类 
  9.  * @author qingfeng 
  10.  * 
  11.  */  
  12. public class User implements Serializable {  
  13.     /** 
  14.      * ID 
  15.      */  
  16.     private int id;  
  17.     /** 
  18.      * 名字 
  19.      */  
  20.     private String name;  
  21.     /** 
  22.      * 类别 
  23.      */  
  24.     private Type type;  
  25.       
  26.     /** 
  27.      * 默认构造方法 
  28.      */  
  29.     public User() {}  
  30.       
  31.     /** 
  32.      * 构造方法 
  33.      * @param id 
  34.      * @param name 
  35.      * @param type 
  36.      */  
  37.     public User(int id, String name, Type type) {  
  38.         super();  
  39.         this.id = id;  
  40.         this.name = name;  
  41.         this.type = type;  
  42.     }  
  43.     public int getId() {  
  44.         return id;  
  45.     }  
  46.     public void setId(int id) {  
  47.         this.id = id;  
  48.     }  
  49.     public String getName() {  
  50.         return name;  
  51.     }  
  52.     public void setName(String name) {  
  53.         this.name = name;  
  54.     }  
  55.     public Type getType() {  
  56.         return type;  
  57.     }  
  58.     public void setType(Type type) {  
  59.         this.type = type;  
  60.     }  
  61. }  

再写一个用户类别类,如下:

[java] view plaincopyprint?
  1. View Code   
  2.   
  3. package com.my.test;  
  4.   
  5. import java.io.Serializable;  
  6.   
  7. /** 
  8.  * 用户类别 
  9.  * @author qingfeng 
  10.  * 
  11.  */  
  12. public class Type implements Serializable {  
  13.     /** 
  14.      * ID 
  15.      */  
  16.     private int id;  
  17.     /** 
  18.      * 类别名称 
  19.      */  
  20.     private String name;  
  21.       
  22.     /** 
  23.      * 默认构造方法 
  24.      */  
  25.     public Type() {}  
  26.     /** 
  27.      * 构造方法 
  28.      * @param id 
  29.      * @param name 
  30.      */  
  31.     public Type(int id, String name) {  
  32.         super();  
  33.         this.id = id;  
  34.         this.name = name;  
  35.     }  
  36.     public int getId() {  
  37.         return id;  
  38.     }  
  39.     public void setId(int id) {  
  40.         this.id = id;  
  41.     }  
  42.     public String getName() {  
  43.         return name;  
  44.     }  
  45.     public void setName(String name) {  
  46.         this.name = name;  
  47.     }  
  48. }  

现在,我们写一个示例类,演示gson的一般用户法,代码如下:
[java] view plaincopyprint?
  1. View Code   
  2.   
  3. package com.my.test;  
  4.   
  5. import java.util.ArrayList;  
  6. import java.util.HashMap;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9.   
  10. import com.google.gson.ExclusionStrategy;  
  11. import com.google.gson.FieldAttributes;  
  12. import com.google.gson.Gson;  
  13. import com.google.gson.GsonBuilder;  
  14.   
  15. /** 
  16.  * 对象转换成json 
  17.  * @author qingfeng 
  18.  */  
  19. public class Object2Json {  
  20.   
  21.     public static void main(String[] args) {  
  22.           
  23.         //list示例  
  24.         List2Json();  
  25.           
  26.         //map示例  
  27.         Map2Json();  
  28.           
  29.         //复杂list示例  
  30.         ComplexList2Json();  
  31.           
  32.         //复杂map示例  
  33.         ComplexMap2Json();  
  34.     }  
  35.     /** 
  36.      * 简单list集合转换json数组 
  37.      */  
  38.     public static void List2Json() {  
  39.         //创建一个list  
  40.         List<Type> list = new ArrayList<Type>();  
  41.         for(int i = 0; i < 5; i ++) {  
  42.             list.add(new Type(i, "类别" + i));  
  43.         }  
  44.           
  45.         //创建一个gson对象  
  46.         Gson gson = new Gson();  
  47.           
  48.         //转换成json  
  49.         String json = gson.toJson(list);  
  50.           
  51.         //输出结果  
  52.         System.out.println(json);  
  53.     }  
  54.     /** 
  55.      * 简单map转换成json 
  56.      */  
  57.     public static void Map2Json() {  
  58.         //创建一个map  
  59.         Map<String, Type> map = new HashMap<String, Type>();  
  60.         for(int i = 0; i < 5; i ++) {  
  61.             map.put("编号" + i, new Type(i, "类别" + i));  
  62.         }  
  63.           
  64.         //创建一个gson对象  
  65.         Gson gson = new Gson();  
  66.           
  67.         //转换成json  
  68.         String json = gson.toJson(map);  
  69.           
  70.         //输出结果  
  71.         System.out.println(json);  
  72.     }  
  73.       
  74.     /** 
  75.      * 复杂list转换成json 
  76.      */  
  77.     public static void ComplexList2Json() {  
  78.         //创建一个list  
  79.         List<User> list = new ArrayList<User>();  
  80.           
  81.         //创建几个用户类别  
  82.         Type t1 = new Type(1"老师");  
  83.         Type t2 = new Type(2"学生");  
  84.           
  85.         //创建几个用户  
  86.         User u1 = new User(1"张三", t1);  
  87.         User u2 = new User(2"李四", t1);  
  88.         User u3 = new User(3"王五", t2);  
  89.           
  90.         //将用户添加到list  
  91.         list.add(u1);  
  92.         list.add(u2);  
  93.         list.add(u3);  
  94.           
  95.         //先创建一个gson对象  
  96.         Gson gson = new Gson();  
  97.           
  98.         //将list转换成json  
  99.         String json = gson.toJson(list);  
  100.           
  101.         //将结果输出  
  102.         System.out.println(json);  
  103.     }  
  104.       
  105.     /** 
  106.      * 复杂map转换成json 
  107.      */  
  108.     public static void ComplexMap2Json() {  
  109.         //创建一个map  
  110.         Map<String, User> map = new HashMap<String, User>();  
  111.           
  112.         //创建几个用户类别  
  113.         Type t1 = new Type(1"老师");  
  114.         Type t2 = new Type(2"学生");  
  115.           
  116.         //创建几个用户  
  117.         User u1 = new User(1"张三", t1);  
  118.         User u2 = new User(2"李四", t1);  
  119.         User u3 = new User(3"王五", t2);  
  120.           
  121.         //将用户添加到map  
  122.         map.put(u1.getName(), u1);  
  123.         map.put(u2.getName(), u2);  
  124.         map.put(u3.getName(), u3);  
  125.           
  126.         //这里的map的key已经设置了用户的name了  
  127.         //我们希望它的value里面包含对应的type和id就行了,不需要name属性  
  128.         //而它的type里面的name和id还是要的  
  129.         //所以,我们要给gson对象设置过滤条件  
  130.           
  131.         //设置要输出的属性  
  132.         final String regUser = "|type|id|";  
  133.         final String regOther = "|id|name|";  
  134.           
  135.         //创建一个带过滤条件的gson对象  
  136.         Gson gson = new GsonBuilder()  
  137.             .setExclusionStrategies(new ExclusionStrategy() {  
  138.                   
  139.                 /** 
  140.                  * 设置要过滤的属性 
  141.                  */  
  142.                 @Override  
  143.                 public boolean shouldSkipField(FieldAttributes attr) {  
  144.                     //我们只过滤User类的id属性,而Type类的id属性还是要输出的  
  145.                     boolean b = false;  
  146.                     //如果当前属性所在的类是User的话,就使用regUser过滤  
  147.                     //否则就用regOther来过滤  
  148.                     if(attr.getDeclaringClass() == User.class) {  
  149.                         b = regUser.contains("|" + attr.getName() + "|");  
  150.                     } else {  
  151.                         b = regOther.contains("|" + attr.getName() + "|");  
  152.                     }  
  153.                     //这里,如果返回true就表示此属性要过滤,否则就输出  
  154.                     return !b;  
  155.                 }  
  156.                   
  157.                 /** 
  158.                  * 设置要过滤的类 
  159.                  */  
  160.                 @Override  
  161.                 public boolean shouldSkipClass(Class<?> clazz) {  
  162.                     //这里,如果返回true就表示此类要过滤,否则就输出  
  163.                     return false;  
  164.                 }  
  165.             }).create();  
  166.           
  167.         //转换成json  
  168.         String json = gson.toJson(map);  
  169.           
  170.         //将结果输出  
  171.         System.out.println(json);  
  172.     }  
  173. }  

常用技巧:

  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自定义转换策略,一般是可以解决这些问题的。

 

总结:

  分析问题,不要死扣一个地方,要从多个方面分析,重新分析整个程序的执行过程,找出所有可能出现问题的地方,逐一验证,当然这不是一两句话能说清楚的,需要经验。

转自:http://www.cnblogs.com/lang86987182/articles/2179843.html
1 0