Java的JSON转换类库GSON的基础使用教程
gson (github:https://github.com/google/gson)是 google 提供的用来在 java 对象和 json 数据之间进行映射的 java 类库。可以将一个 json 字符串转成一个 java 对象,或者反过来。
gson里最重要的对象有2个gson 和 gsonbuilder。
gson有2个最基本的方法
(1)tojson() – 转换java 对象到json
(2)fromjson() – 转换json到java对象
编写实体类:
public class people { string name; int age; boolean setname; public string getname() { return name; } public void setname(string name) { this.name = name; } public int getage() { return age; } public void setage(int age) { this.age = age; } public boolean getsetname() { return setname; } public void setsetname(boolean setname) { this.setname = setname; } @override public string tostring() { return "name=" + name + " age=" + age + " setname=" +setname; } }
编写测试类gsontest
import com.google.gson.exclusionstrategy; import com.google.gson.fieldattributes; import com.google.gson.gson; import com.google.gson.gsonbuilder; /** * convert java object to json. */ public class gsontest { public static void main(string[] args) { people p = new people(); p.setage(20); p.setname("people"); p.setsetname(true); gson gson = new gson(); system.out.println(gson.tojson(p)); } }
输出结果:
{"name":"people","age":20,"setname":true}
这只是最简单的gson的使用。如果我们需要将bool类型的属性setname在转换成json的时候不转换,怎么实现呢?
在gson的包中找半天,发现com.google.gson包下面有这么一个接口:exclusionstrategy ,虽然不清楚是干什么的,但是根据名字,可以推断,这个接口是用来设置gson转换的排除策略的,于是在官网http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/index.html查了一下这个接口,发现只要实现这个接口,并将实现类的对象塞给gson,在转换成json的时候,gson就会过滤掉指定的类或者属性。于是有了下面的代码:
import com.google.gson.exclusionstrategy; import com.google.gson.fieldattributes; import com.google.gson.gson; import com.google.gson.gsonbuilder; /** * convert java object to json, skip specific fileds. */ public class gsontest { public static void main(string[] args) { people p = new people(); p.setage(20); p.setname("people"); p.setsetname(true); exclusionstrategy excludestrategy = new setterexclusionstrategy(); gson gson1 = new gsonbuilder() .setexclusionstrategies(excludestrategy) .create(); gson gson2 = new gson(); string json1 = gson1.tojson(p); string json2 = gson2.tojson(p); system.out.println(json1); system.out.println(json2); people p1 = gson1.fromjson(json1, people.class); people p2 = gson2.fromjson(json2, people.class); system.out.println(p1); system.out.println(p2); } private static class setterexclusionstrategy implements exclusionstrategy { public boolean shouldskipclass(class<?> clazz) { return false; } public boolean shouldskipfield(fieldattributes f) { return f.getname().startswith("set"); } } }
原来,gson对象的创建有两种方式:new gson()表示使用默认的配置创建一个gson对象,而如果使用gsonbuilder.create()方法创建,则可以自定义一些设置,这主要是为了使创建的gson更适合于某些特定的情况。上例中第一段蓝色的代码创建了一个gson对象,这个对象拥有对以“set”字样开头的属性的过滤的配置(如果需要过滤掉某种类型,则重写exclusionstrategy接口的shouldskipclass(class<?> clazz)方法即可,如果需要过滤掉多种情况,则可以多创建几个exclusionstrategy的实现类对象,并在创建gson对象的时候设置进去即可),因此在本例中,将people对象转换成json的时候,属性setname将被过滤掉。由于json1中没有属性setname,所以将json1反序列化成people对象的时候,boolean类型的setname就没有了值,所以打印的时候取了boolean类型的默认值。于是有了以下结果:
{"name":"people","age":20} {"name":"people","age":20,"setname":true} name=people age=20 setname=false name=people age=20 setname=true
gson还支持使用注解,在com.google.gson.annotation包中,有几个注解expose, serializedname, since和until,他们各有各的作用,下面使用官方例子介绍常用的注解:
expose:
此注解作用在属性上,表明当序列化和反序列化的时候,这个属性将会暴露给gson对象。这个注解只有当创建gson对象时使用gsonbuilder方式创建并调用了gsonbuilder.excludefieldswithoutexposeannotation() 方法的时候才有效,否则无效。下面是一个介绍@expose注解如何使用的例子:
public class user { @expose private string firstname; @expose(serialize = false) private string lastname; @expose (serialize = false, deserialize = false) private string emailaddress; private string password; }
如果你以new gson()的方式创建gson对象,tojson()方法和fromjson() 方法在序列化和反序列化的时候将会操作这4个属性。然而,如果你使用 gson gson = new gsonbuilder().excludefieldswithoutexposeannotation().create()来创建gson对象,gson 的 tojson() 和 fromjson() 方法将会排除掉 password 字段,这是因为 password 字段没有被注解 @expose 所标记。 这个 gson 对象同样会排除 lastname 和 emailaddress 字段,因为注解@expose的属性 serialize 被设置成了 false。类似的,gson 将会在反序列化时排除掉 emailaddress 字段,因为 deserialize被设置成了 false。
serializedname:
此注解作用在属性上,表明这个属性在序列化成json的时候,需要将名字序列化成注解的value属性指定的值。
这个注解将会覆盖任何的fieldnamingpolicy, 包括默认的命名策略。下面是一个介绍@serializedname注解如何使用的例子: ,
public class someclasswithfields { @serializedname("name") private final string somefield; private final string someotherfield; public someclasswithfields(string a, string b) { this.somefield = a; this.someotherfield = b; } }
下面的代码展示了序列化上面这个测试类的结果:
someclasswithfields objecttoserialize = new someclasswithfields("a", "b"); gson gson = new gson(); string jsonrepresentation = gson.tojson(objecttoserialize); system.out.println(jsonrepresentation);
执行结果是:
{"name":"a","someotherfield":"b"}
由此可见,属性"somefield"已经被序列化成了"name"。
注意:在@serializedname的value中指定的属性名必须为有效的json属性名。