介绍:
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;
- }
- }
再写一个用户类别类,如下:
- View Code
- 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的一般用户法,代码如下:
- View Code
- 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自定义转换策略,一般是可以解决这些问题的。
总结:
分析问题,不要死扣一个地方,要从多个方面分析,重新分析整个程序的执行过程,找出所有可能出现问题的地方,逐一验证,当然这不是一两句话能说清楚的,需要经验。
转自:http://www.cnblogs.com/lang86987182/articles/2179843.html