Android框架---Google官方Gson解析(上)

原创 2017年09月28日 14:41:04

Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成,广泛应用于各种数据的交互中,尤其是服务器与客户端的交互。

GitHub中的源码地址:https://github.com/google/gson

AS在项目的app目录下的buile.gradle添加gson依赖:(如果需要jar包,文末可以下载)



Gson的实例化方式:

Gson gson = new Gson();
//可以通过GsonBuilder配置多种选项
gson = new GsonBuilder()
        .setLenient()// json宽松
        .enableComplexMapKeySerialization()//支持Map的key为复杂对象的形式
        .serializeNulls() //智能null
        .setPrettyPrinting()// 调教格式
        .disableHtmlEscaping() //默认是GSON把HTML 转义的
        .create();

接下来介绍Gson的集中基本用法:

1、对象和json字符串的相互转换(先准备一个Person类)

public class Person {
	private int per_id;
	private String name;
	private String sex;
	private int age;

	public Person(int per_id, String name, String sex, int age) {
		this.per_id = per_id;
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	
	//get、set和toString方法...
}

测试代码:

/**
 * Created by Layne_Yao on 2017-9-28 上午10:46:43.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class GsonTest {

	public static void main(String[] args) {
		Gson gson = new Gson();
		// 可以通过GsonBuilder配置多种选项
		gson = new GsonBuilder()
				.setLenient()// json宽松
				.enableComplexMapKeySerialization()// 支持Map的key为复杂对象的形式
				.serializeNulls() // 智能null
				.setPrettyPrinting()// 调教格式
				.disableHtmlEscaping() // 默认是GSON把HTML 转义的
				.create();

		Person person = new Person(10, "layne", "man", 18);
		// 对象转换为json字符串
		String str = gson.toJson(person);
		System.out.println("对象转换为json字符串:" + str);

		// json字符串转化为对象
		Person person1 = gson.fromJson(str, Person.class);
		System.out.println("json字符串转化为对象:" + person1.toString());

	}

}

运行结果:



2、集合和json字符串之间的转换:

/**
 * Created by Layne_Yao on 2017-9-28 上午11:03:21.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class CollectionTest {
	public static void main(String[] args) {
		Gson gson = new Gson();

		// 1.1、List字符串集合转换为字符串
		ArrayList<String> str_list = new ArrayList<>();
		for (int i = 0; i < 5; i++) {
			str_list.add("这是字符串" + i);
		}
		String json_str = gson.toJson(str_list);
		System.out.println("这是list字符串集合转化为json:" + json_str);
		
		// 1.2、这是json集合转化为list字符集合
		Type type = new TypeToken<ArrayList<String>>() {
		}.getType();
		ArrayList<String> sList = gson.fromJson(json_str, type);
		System.out.println("这是json集合转化为list字符集合:" + sList);
		System.out.println("==========================================");
		
		
		// 2.1、List对象集合转换为字符串
		List<Person> list = new ArrayList<>();
		for (int i = 0; i < 2; i++) {
			Person person = new Person(i, "layne", "man", 18);
			list.add(person);
		}
		String json_str1 = gson.toJson(list);
		System.out.println("这是list对象集合转化为json:" + json_str1);
		
		// 2.1、这是json转化为List对象集合
		Type type1 = new TypeToken<ArrayList<Person>>() {
		}.getType();
		ArrayList<String> sList1 = gson.fromJson(json_str1, type1);
		System.out.println("这是json转化为List对象集合:" + sList1);
		System.out.println("==========================================");
		
		
		//3.1、这是map集合转化为json
		Map<String, Object> map = new HashMap<>();
		map.put("per_id", 5);
		map.put("name", "layne");
		map.put("sex", "man");
		map.put("age", "18");
		
		String json_str2 = gson.toJson(map);
		System.out.println("这是map集合转化为json:" + json_str2);
		
		//3.2、从json字符串转化为map集合
		Type type2 = new TypeToken<Map<String, Object>>() {
		}.getType();
		Map<String, Object> map1 = gson.fromJson(json_str2, type2);
		System.out.println("这是json转化为map集合:" + map1);
		
	}
}

运行结果:


接下来介绍抽象基类JsonElement的继承体系类:

JSONObject、JSONArray和Android自带的差不多,参见上篇Android网络传输数据json解析的基本认识

JsonNull:实际上就是null的字符串字段

JsonPrimitive:这个其实挺有意思的,我们知道如果json转换成字符串会包含引号的转义,但是通过JsonPrimative我们可以获得为转义的字符串

/**
 * Created by Layne_Yao on 2017-9-28 下午1:52:31.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class JsonTest {

	public static void main(String[] args) {
		// JsonNull jsonNull = new JsonNull();// 构造方法过时,推荐INSTANCE

		JsonNull jsonNull = JsonNull.INSTANCE;
		System.out.println("JsonNull:" + jsonNull);

		
		Gson gson = new Gson();
		Person person = new Person(1, "layne", "man", 18);
		String json_str = gson.toJson(person);
		System.out.println("json字符串:" + json_str);

		JsonPrimitive jsonPrimitive = new JsonPrimitive(json_str);
		System.out.println("JsonPrimitive字符串:" + jsonPrimitive);// 多了转义字符,以及头尾的双引号:"{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"age\":18}"
		System.out.println("JsonPrimitive字符串:" + jsonPrimitive.getAsString());	
	}
}

运行结果:



Gson库中的注解:有五种注解


首先着重的先说明重命名注解:SerializedName

注解的作用:转换key关键字,json转换成对象是,json字段的key默认必须和声明类的字段名称一样。但是如果服务器返回的数据中key是关键字,这该怎么办?例如key是case、switch等,我们在声明类的时候是不能用这些字段的。或许你会让服务端那边改动,那服务端可能要改动非常的大,但是实际情况是不太愿意去改的。而这时候重命名注解就派上用场了。
还有就是如果服务端返回的json的key太冗余、或是不直观,这是就可以简化一下,代码看起来比较的优雅。

替换关键字的key:

/**
 * Created by Layne_Yao on 2017-9-28 下午4:08:23.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class AnnotationTest {
	public class Person {
		private int per_id;
		private String name;
		private String sex;
		@SerializedName("case")
		private int case_num;

		public Person(int per_id, String name, String sex, int case_num) {
			super();
			this.per_id = per_id;
			this.name = name;
			this.sex = sex;
			this.case_num = case_num;
		}

		@Override
		public String toString() {
			return "Person-->[per_id=" + per_id + ", name=" + name + ", sex="
					+ sex + ", case_num=" + case_num + "]";
		}

	}

	public static void main(String[] args) {
		Gson gson = new Gson();
		String json_str = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"case\":18}";
		Person person = gson.fromJson(json_str, Person.class);
		System.out.println("服务端发送的情况:"+json_str);
		System.out.println("移动端转换的情况:"+person);
	}

}

运行结果:



替换冗余、难看的key:

/**
 * Created by Layne_Yao on 2017-9-28 下午4:16:44.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class AnnotationTest1 {
	public class Person {
		private int per_id;
		private String name;
		private String sex;
		@SerializedName("home_light_state")
		private boolean state;

		public Person(int per_id, String name, String sex, boolean state) {
			super();
			this.per_id = per_id;
			this.name = name;
			this.sex = sex;
			this.state = state;
		}

		@Override
		public String toString() {
			return "Person [per_id=" + per_id + ", name=" + name + ", sex="
					+ sex + ", state=" + state + "]";
		}
	}

	public static void main(String[] args) {
		Gson gson = new Gson();
		String json_str = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"home_light_state\":true}";
		Person person = gson.fromJson(json_str, Person.class);
		System.out.println("服务端发送的情况:"+json_str);
		System.out.println("移动端转换的情况:"+person);
	}

}

运行结果:



注解作用2:结合alternate 提供多种备用字段key来解析,@SerializedName(value = "state", alternate = { "plus", "all" })
如果json中有plus就会解析成state,如果有all也会解析成state,当然state依旧不变的。
注意1:value中的值不能出现在alternate中;
注意2:alternate的备选字段会后面的替换前面的。

实例代码:

/**
 * Created by Layne_Yao on 2017-9-28 下午5:05:44.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class AnnotationTest2 {
	public class Person {
		private int per_id;
		private String name;
		private String sex;
		@SerializedName(value = "state", alternate = { "plus", "all" })
		private String state;

		public Person(int per_id, String name, String sex, String state) {
			super();
			this.per_id = per_id;
			this.name = name;
			this.sex = sex;
			this.state = state;
		}

		@Override
		public String toString() {
			return "Person [per_id=" + per_id + ", name=" + name + ", sex="
					+ sex + ", state=" + state + "]";
		}
	}

	public static void main(String[] args) {
		Gson gson = new Gson();
		String json_str = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"all\":\"广东广州\"}";
		Person person = gson.fromJson(json_str, Person.class);
		System.out.println("服务端发送:"+json_str);
		System.out.println("转换成:" + person);
		System.out.println("==========================");

		String json_str1 = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"plus\":\"广东广州\"}";
		Person person1 = gson.fromJson(json_str1, Person.class);
		System.out.println("服务端发送:"+json_str1);
		System.out.println("转换成:" + person1);
		System.out.println("==========================");
		
		//all在state之后,所以all会解析成state,值则是all的原先的值
		String json_str2 = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"state\":\"state广东广州\",\"all\":\"all广东广州\"}";
		Person person2 = gson.fromJson(json_str2, Person.class);
		System.out.println("服务端发送:"+json_str2);
		System.out.println("转换成:" + person2);
		System.out.println("==========================");
		
		//state在最后,不用解析,解析后的值也是state原先的
		String json_str3 = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"plus\":\"plus广东广州\",\"state\":\"all广东广州\"}";
		Person person3 = gson.fromJson(json_str3, Person.class);
		System.out.println("服务端发送:"+json_str3);
		System.out.println("转换成:" + person3);
		System.out.println("==========================");
	}

}

运行结果:


过滤注解:Expose

源码:默认既可序列化又可反序列化

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Expose {
  
  public boolean serialize() default true;

  public boolean deserialize() default true;
}

可以排除不需要序列化的字段,需要配合GsonBuilder使用

Gson gson = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                .create();

不添加@Expose注解的字段将不会解析,分为以下几种情况:

1、不添加@Expose注解等同于@Expose(deserialize = false,serialize = false) 不做任何解析
2、@Expose(deserialize = true,serialize = false) 只解析用用,也就是反序列化可以,序列化不可以
3、@Expose(deserialize = false,serialize = true) 序列化可以,反序列化不行
4、@Expose(deserialize = true,serialize = true) 既可以序列化,也可以反序列化

实例代码:不添加@Expose注解等同于@Expose(deserialize = false,serialize = false) 不做任何解析

/**
 * Created by Layne_Yao on 2017-9-29 上午9:29:08.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class ExposeTest {
	public static class Person {
		private int per_id;
		private String name;
		private String sex;
		private boolean state;

		public Person(int per_id, String name, String sex, boolean state) {
			this.per_id = per_id;
			this.name = name;
			this.sex = sex;
			this.state = state;
		}

		@Override
		public String toString() {
			return "Person-->[per_id=" + per_id + ", name=" + name + ", sex="
					+ sex + ", state=" + state + "]";
		}

	}

	public static void main(String[] args) {
		String json_str = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"state\":true}";
		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
				.create();

		Person person = gson.fromJson(json_str, Person.class);
		System.out.println("反序列化:" + person);

		Person person1 = new Person(2, "layne", "man", true);
		String json_str1 = gson.toJson(person1);
		System.out.println("序列化:"+json_str1);
	}
}

运行结果:



@Expose(deserialize = true,serialize = false) 只解析用用,也就是反序列化可以,序列化不可以

/**
 * Created by Layne_Yao on 2017-9-29 上午9:59:04.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class ExposeTest3 {
	public static class Person {
		@Expose(deserialize = true,serialize = false)
		private int per_id;
		@Expose(deserialize = true,serialize = false)
		private String name;
		@Expose(deserialize = true,serialize = false)
		private String sex;
		@Expose(deserialize = true,serialize = false)
		private boolean state;

		public Person(int per_id, String name, String sex, boolean state) {
			this.per_id = per_id;
			this.name = name;
			this.sex = sex;
			this.state = state;
		}

		@Override
		public String toString() {
			return "Person-->[per_id=" + per_id + ", name=" + name + ", sex="
					+ sex + ", state=" + state + "]";
		}

	}
	public static void main(String[] args) {
		String json_str = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"state\":true}";
		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
				.create();

		Person person = gson.fromJson(json_str, Person.class);
		System.out.println("反序列化:" + person);

		Person person1 = new Person(2, "layne", "man", true);
		String json_str1 = gson.toJson(person1);
		System.out.println("序列化:"+json_str1);
	}
}

运行结果:



@Expose(deserialize = false,serialize = true) 序列化可以,反序列化不行

/**
 * Created by Layne_Yao on 2017-9-29 上午9:56:57.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class ExposeTest2 {
	public static class Person {
		@Expose(deserialize = false,serialize = true)
		private int per_id;
		@Expose(deserialize = false,serialize = true)
		private String name;
		@Expose(deserialize = false,serialize = true)
		private String sex;
		@Expose(deserialize = false,serialize = true)
		private boolean state;

		public Person(int per_id, String name, String sex, boolean state) {
			this.per_id = per_id;
			this.name = name;
			this.sex = sex;
			this.state = state;
		}

		@Override
		public String toString() {
			return "Person-->[per_id=" + per_id + ", name=" + name + ", sex="
					+ sex + ", state=" + state + "]";
		}

	}
	public static void main(String[] args) {
		String json_str = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"state\":true}";
		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
				.create();

		Person person = gson.fromJson(json_str, Person.class);
		System.out.println("反序列化:" + person);

		Person person1 = new Person(2, "layne", "man", true);
		String json_str1 = gson.toJson(person1);
		System.out.println("序列化:"+json_str1);
	}
}

运行结果:



@Expose(deserialize = true,serialize = true) 既可以序列化,也可以反序列化

/**
 * Created by Layne_Yao on 2017-9-29 上午9:53:38.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class ExposeTest1 {
	public static class Person {
		@Expose //等同于 @Expose(deserialize = true,serialize = true)
		private int per_id;
		@Expose
		private String name;
		@Expose
		private String sex;
		@Expose
		private boolean state;

		public Person(int per_id, String name, String sex, boolean state) {
			this.per_id = per_id;
			this.name = name;
			this.sex = sex;
			this.state = state;
		}

		@Override
		public String toString() {
			return "Person-->[per_id=" + per_id + ", name=" + name + ", sex="
					+ sex + ", state=" + state + "]";
		}

	}

	public static void main(String[] args) {
		String json_str = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"state\":true}";
		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
				.create();

		Person person = gson.fromJson(json_str, Person.class);
		System.out.println("反序列化:" + person);

		Person person1 = new Person(2, "layne", "man", true);
		String json_str1 = gson.toJson(person1);
		System.out.println("序列化:"+json_str1);

	}

}

运行结果:



版本控制注解:Since、Util

Since注解:Gson实例配置GsonBuilder.setVersion(n)使用,当n>=v时,才会序列化解析

实例代码:

/**
 * Created by Layne_Yao on 2017-9-29 上午10:00:37.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class SinceTest {
	public static class Person {
		 @Since(2)
		private int per_id;
		 @Since(2)
		private String name;
		 @Since(2)
		private String sex;
		 @Since(2)
		private boolean state;

		public Person(int per_id, String name, String sex, boolean state) {
			this.per_id = per_id;
			this.name = name;
			this.sex = sex;
			this.state = state;
		}

		@Override
		public String toString() {
			return "Person-->[per_id=" + per_id + ", name=" + name + ", sex="
					+ sex + ", state=" + state + "]";
		}

	}
	public static void main(String[] args) {
		String json_str = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"state\":true}";
		Gson gson = new GsonBuilder().setVersion(1)//版本为1
				.create();

		Person person = gson.fromJson(json_str, Person.class);
		System.out.println("反序列化v=1:" + person);

		Person person1 = new Person(2, "layne", "man", true);
		String json_str1 = gson.toJson(person1);
		System.out.println("序列化v=1:"+json_str1);
		System.out.println("=================================");
		
		Gson gson1 = new GsonBuilder().setVersion(2)//版本为2
				.create();
		Person person2 = gson1.fromJson(json_str, Person.class);
		System.out.println("反序列化v=2:" + person2);

		Person person3 = new Person(2, "layne", "man", true);
		String json_str2 = gson1.toJson(person3);
		System.out.println("序列化v=2:"+json_str2);
		System.out.println("=================================");
		
		Gson gson2 = new GsonBuilder().setVersion(3)//版本为3
				.create();
		Person person4 = gson2.fromJson(json_str, Person.class);
		System.out.println("反序列化v=3:" + person4);

		Person person5 = new Person(2, "layne", "man", true);
		String json_str3 = gson2.toJson(person5);
		System.out.println("序列化v=3:"+json_str3);
	}

}

运行结果:



Util注解:Gson实例配置GsonBuilder.setVersion(n)使用,当n<v时,才会序列化解析

实例代码:

/**
 * Created by Layne_Yao on 2017-9-29 上午10:17:54.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class UtilTest {
	public static class Person {
		@Until(2)
		private int per_id;
		@Until(2)
		private String name;
		@Until(2)
		private String sex;
		@Until(2)
		private boolean state;

		public Person(int per_id, String name, String sex, boolean state) {
			this.per_id = per_id;
			this.name = name;
			this.sex = sex;
			this.state = state;
		}

		@Override
		public String toString() {
			return "Person-->[per_id=" + per_id + ", name=" + name + ", sex="
					+ sex + ", state=" + state + "]";
		}
	}

	public static void main(String[] args) {
		String json_str = "{\"per_id\":1,\"name\":\"layne\",\"sex\":\"man\",\"state\":true}";
		Gson gson = new GsonBuilder().setVersion(1)// 版本为1
				.create();

		Person person = gson.fromJson(json_str, Person.class);
		System.out.println("反序列化v=1:" + person);

		Person person1 = new Person(2, "layne", "man", true);
		String json_str1 = gson.toJson(person1);
		System.out.println("序列化v=1:" + json_str1);
		System.out.println("=================================");

		Gson gson1 = new GsonBuilder().setVersion(2)// 版本为2
				.create();
		Person person2 = gson1.fromJson(json_str, Person.class);
		System.out.println("反序列化v=2:" + person2);

		Person person3 = new Person(2, "layne", "man", true);
		String json_str2 = gson1.toJson(person3);
		System.out.println("序列化v=2:" + json_str2);
		System.out.println("=================================");

		Gson gson2 = new GsonBuilder().setVersion(3)// 版本为3
				.create();
		Person person4 = gson2.fromJson(json_str, Person.class);
		System.out.println("反序列化v=3:" + person4);

		Person person5 = new Person(2, "layne", "man", true);
		String json_str3 = gson2.toJson(person5);
		System.out.println("序列化v=3:" + json_str3);

	}

}

运行结果:


Gson2.7jar包下载

版权声明:欢迎以任何形式转载,但请注明作者和出处

android-gson使用

android gson的使用
  • chenyannan0617
  • chenyannan0617
  • 2016年07月14日 20:53
  • 2114

Gson的详细使用(android必备,快速提高开发效率)

Gson的详细使用(android必备,快速提高开发效率)         接下来我要强烈给大家推荐一个google官方推荐使用的json解析库Gson。掌握好它之后,在以后的开发中就会减少非常多的代...
  • oQiHaoGongYuan
  • oQiHaoGongYuan
  • 2016年03月21日 14:34
  • 10893

在Android Studio中如何添加GSON 并使用GsonFormat快速实现实体类

方法一: 1.在Android Studio中按F4快捷键进入Project Structure 2点击+号 . 3.选择Library dependency 4.搜索GSON 5.添加进去 方法...
  • xin917480852
  • xin917480852
  • 2016年03月15日 00:12
  • 31568

android Gson的使用

相对于较为传统的Json解析来说,google共享的开源Gson在解析速度和所使用的内存在有着明显的优势,虽然说阿里巴巴也提供了fastgson包,但是它跟Gson的处理速度大同小异,只是底层实现的原...
  • kongzhichen
  • kongzhichen
  • 2013年08月21日 11:08
  • 42268

Android:用GSON 五招之内搞定任何JSON数组

写在前面原文  http://www.iamxiarui.com/2016/08/30/android:用gson-五招之内搞定任何json数组/ 关于GSON的入门级使用,这里...
  • qq_35114086
  • qq_35114086
  • 2016年09月29日 22:57
  • 5494

Android-Gson+GsonFormat的导入

参考:GsonFormat的使用gson的相关类一、Android Studio快速添加Gson1、File->Project Structure: 2、app->Dependencies->”+”...
  • sinat_31057219
  • sinat_31057219
  • 2017年05月09日 09:54
  • 495

Android用Gson解析Json

转载请标明出处:http://blog.csdn.net/wu_wxc/article/details/53706000 本文出自【吴孝城的CSDN博客】 Gson是谷歌推出的,目前解析Json...
  • wu_wxc
  • wu_wxc
  • 2016年12月17日 11:51
  • 1493

Android:使用Gson解析复杂的JSON数据

本文主要讲解android如何解析复杂格式的JSON数据,适合android初学者和初步接触JSON的人。...
  • u012028501
  • u012028501
  • 2016年04月23日 13:00
  • 7049

Android之gson操作系列1

Android之gson操作系列1文章链接:http://blog.csdn.net/qq_16628781/article/details/64246167知识点: json的简介; json和XM...
  • qq_16628781
  • qq_16628781
  • 2017年03月21日 00:53
  • 314

Android的Gson的使用方法,实现Json结构间相互转换

一,把数组,对象,List,Map等数据结构转换成Json字符串 import java.lang.reflect.Type; import java.util.ArrayList; import ...
  • tuke_tuke
  • tuke_tuke
  • 2016年05月31日 10:16
  • 5196
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android框架---Google官方Gson解析(上)
举报原因:
原因补充:

(最多只允许输入30个字)