Gson详解:Java对象与JSON相互转换的利器

1. Gson是什么(What is Gson)

Gson是一个开源的Java库,用于任意Java对象与JSON之间的相互转换,由Google开发维护。

Gson的优势:

  • 简单易用:以toJsonfromJson两个方法为核心
  • 不需要annotations的支持,可以在缺少源代码或不方便修改源代码的情况下使用
  • 支持泛型和集合

github: https://github.com/google/gson
API Spec: http://google.github.io/gson/apidocs/

2. 将Gson引入项目

  • 在Maven中加入依赖
<dependency>
	<groupId>com.google.code.gson</groupId>
	<artifactId>gson</artifactId>
	<version>2.5</version>
</dependency>
  • 将jar直接加入项目的lib文件夹

为了图省事,我把相应jar放在我的百度云。(其实是把maven下载的版本打包而已)

3. 示例(How to use)

3.1 --自定义测试类--

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
}

3.2 序列化

Java对象 → JSON:toJson(Object)

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)中。(亲测)
 */

3.3 反序列化

JSON → Java对象:fromJson(String, Type)

  • 反序列化时,必须提供反序列化的类型java.lang.reflect.Type
  • 对于普通的引用类型(Object子类),可使用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());
}

3.4 重定向数据来源/输出

默认情况下,toJson(Object)将生成的JSON数据保存在一个StringWriter中;fromJson(String, Type)则是从String中读取。可传入相应WriterReader改变数据的去处或来源。

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,所以其子类都满足这个条件
 */

3.5 --修改自定义测试类--

Person类增加两个变量:

  • geo:长度为2的double数组用于表示地理位置,即经纬度
  • Account
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:

public class Account {
	private String id;
	private String email;	
	private Date dateOfRegister = new Date();
	/* setter/getter */
}

3.6 自定义输出格式

通过修改GsonBuilder的属性,自定义输出的结果:

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.7 操作JSON树

将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));

4. 说明

以上内容均参考官方文档,如有错误,还望指正。

转载于:https://my.oschina.net/SCVTheDefect/blog/545844

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Gson是Google的一个开源项目,可以将Java对象转换JSON,也可能将JSON转换Java对象Gson里最重要的对象有2个GsonGsonBuilder Gson有2个最基本的方法 1) toJson() – 转换java 对象JSON 2) fromJson() – 转换JSONjava对象 下面是几个小例子 1. toJson() example Java 代码 收藏代码 1. class TestObjectToJson { 2. private int data1 = 100; 3. private String data2 = "hello"; 4. } 5. 6. TestObjectToJson obj = new TestObjectToJson(); 7. Gson gson = new Gson(); 8. String json = gson.toJson(obj); class TestObjectToJson { private int data1 = 100; private String data2 = "hello"; } TestObjectToJson obj = new TestObjectToJson(); Gson gson = new Gson(); String json = gson.toJson(obj); 会输出 {"data1":100,"data2":"hello"} 2. fromJson() example Java 代码 收藏代码 1. import com.google.gson.Gson; 2. 3. class TestJsonFromObject { 4. private int data1; 5. private String data2; 6. } 7. 8. String json = "{'data1':100,'data2':'hello'}"; 9. Gson gson = new Gson(); 10. TestJsonFromObject obj = gson.fromJson(json, TestJsonFromObject.class); import com.google.gson.Gson; class TestJsonFromObject { private int data1; private String data2; } String json = "{'data1':100,'data2':'hello'}"; Gson gson = new Gson(); TestJsonFromObject obj = gson.fromJson(json, TestJsonFromObject.class); 3. 将Java对象的属性转换成指定的JSON名字 Java 代码 收藏代码 1. import com.google.gson.FieldNamingPolicy; 2. import com.google.gson.Gson; 3. import com.google.gson.GsonBuilder; 4. import com.google.gson.annotations.SerializedName; 5. 6. public class TestGson { 7. 8. @SerializedName("first_field") 9. private String field1; 10. 11. private String secondField; 12. 13. public TestGson(String param1, String param2) { 14. field1 = param1; 15. secondField = param2; 16. } 17. } 18. 19. TestGson obj = new TestGson("aaaa", "bbbbb"); 20. Gson gson = new Gson
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值