Gson是一个开源的Java库,用于任意Java对象与JSON之间的相互转换,由Google开发维护。java
Gson的优点:git
toJson
和fromJson
两个方法为核心github: https://github.com/google/gson
API Spec: http://google.github.io/gson/apidocs/github
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.5</version> </dependency>
为了图省事,我把相应jar放在个人百度云。(实际上是把maven下载的版本打包而已)json
public class Person implements Serializable, Comparable<Person>{ private static final long serialVersionUID = 2373954257153196535L; private String name; private int age; private String gender; //实现Comparable只是为了测试Set的序列化/反序列化,并没有其余意思 public int compareTo(Person o) { if(o == null) return -1; if(this == o) return 0; if(this.getName().equals(o.getName()) && this.getAge() == o.getAge() && this.getGender() == o.getGender()) return 0; return -1; } // a series of setter/getter }
Java对象 → JSON:toJson(Object)
api
Person p1 = new Person("David", 26, "male"); Person p2 = new Person("Annie", 23, "female"); Person p3 = new Person("琼恩", 29, "男"); Gson gson = new Gson();//也能够经过new GsonBuilder().create();来实例化 //单个对象 String json = gson.toJson(p1);//{"name":"David","age":26,"gender":"male"} //List List<Person> list = Arrays.asList(p1, p2, p3); String jsonList = gson.toJson(list); //Set Set<Person> set = new HashSet<Person>(); set.add(p1); set.add(p2); set.add(p1); String jsonSet = gson.toJson(set); //数组:先转换成List Person[] arr = {p1, p2, p3}; List<Person> jsonArrList = Arrays.asList(arr); String jsonArr = gson.toJson(jsonArrList); /* * 关于Java关键字:transient * * transient声明的field(成员变量)在对象序列化时会被忽略, * 经常使用于声明password之类比较敏感的变量。 * transient不能用于声明方法。(反正方法既不会也不必被序列化) * * 因为gson.toJson(obj)涉及序列化,transient在此也会生效, * 即transient声明的变量不会出如今生成的json(String)中。(亲测) */
JSON → Java对象:fromJson(String, Type)
数组
java.lang.reflect.Type
java.lang.Class
对象(实现了Type接口)Type t1 = Person.class; Type t2 = p1.getClass(); boolean flag = (t1 == t2);//true Person person = gson.fromJson(json, t1); System.out.println(person.getName());//David
com.google.gson.reflect.TypeToken
获取其类型Type setType = new TypeToken<Set<Person>>(){}.getType();//TypeToken<T>的Constructor(构造器/构造方法)为protected, 使用匿名内部类的方式进行实例化 Set<Person> people = gson.fromJson(jsonSet, setType); Iterator<Person> ps = people.iterator(); while(ps.hasNext()){ System.out.println(ps.next().getName()); }
默认状况下,toJson(Object)
将生成的JSON数据保存在一个StringWriter
中;fromJson(String, Type)
则是从String中读取。可传入相应Writer
或Reader
改变数据的去处或来源。maven
File f = new File("/Users/Lawrence/Documents/out.txt"); Writer out = new FileWriter(f); gson.toJson(set, out);//将生成的JSON数据保存在文件中,而不是默认的String out.close(); Reader reader = new FileReader(f); Set<Person> setFromFile = gson.fromJson(reader, setType);//从文件中读取数据,而不是默认的String System.out.println(setFromFile.size());//2 reader.close(); /* * 改变数据输出,须要java.lang.Appendable * 事实上Writer就实现了Appendable,因此其子类都知足这个条件 */
Person类增长两个变量:测试
public class Person implements Serializable, Comparable<Person>{ private static final long serialVersionUID = 2373954257153196535L; private String name; private int age; private String gender; private double[] geo = new double[2]; private Account account; /* a series of setter/getter */ }
Account.java:ui
public class Account { private String id; private String email; private Date dateOfRegister = new Date(); /* setter/getter */ }
经过修改GsonBuilder的属性,自定义输出的结果:this
Person p1 = new Person("David", 26, "male"); Account ac = new Account("id", "<h1>test1@test1.com</h1>"); p1.setAccount(ac); Person p2 = new Person("Rose", 23, "女"); Account ac2 = new Account("id2", "<p>test2@test2.com</p>"); p2.setAccount(ac2); Person p3 = new Person(); p3.setName("Hello"); List<Person> list = Arrays.asList(p1, p2, p3); Gson gson = new GsonBuilder() .setPrettyPrinting()//自动换行和添加缩进 .serializeNulls()//保留null的变量并将值设为null .disableHtmlEscaping()//不会对用于表示HTML标签的"<"和">"编码 .setDateFormat("yyyy-MM-dd")//为全部java.util.Date定义输出格式 .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES) //定义变量名的显示方式,如此处将Account的dateOfRegister定义输出为"Date Of Register" .create(); System.out.println(gson.toJson(list));
以上输出为
[ { "Name": "David", "Age": 26, "Gender": "male", "Geo": [ 0.0, 0.0 ], "Account": { "Id": "id", "Email": "<h1>test1@test1.com</h1>", "Date Of Register": "2015-12-16" } }, { "Name": "Rose", "Age": 23, "Gender": "女", "Geo": [ 0.0, 0.0 ], "Account": { "Id": "id2", "Email": "<p>test2@test2.com</p>", "Date Of Register": "2015-12-16" } }, { "Name": "Hello", "Age": 0, "Gender": null, "Geo": [ 0.0, 0.0 ], "Account": null } ]
将3.6中添加的由3个Person对象组成的list为例:
JsonElement root = gson.toJsonTree(list);//3个Person对象 if(root.isJsonArray()){ JsonArray arr = (JsonArray) root; Iterator<JsonElement> iter = arr.iterator(); JsonElement target = null; while(iter.hasNext()){ JsonObject element = (JsonObject) iter.next(); String name = element.get("Name").getAsString(); if("Hello".equals(name)){ // arr.remove(element);//不能调用ArrayList的remove(), 由于会抛出java.util.ConcurrentModificationException iter.remove();//须要调用的是Iterator的remove(); } } } System.out.println(gson.toJson(root));
以上内容均参考官方文档,若有错误,还望指正。