先扯点别的。在写东西之前我总是疑问到底写不写,网上已经有很多人早就写完了,写的比我写的好,比我写的早,那我写这些东西还有意义吗?答案是:对我是有意义的。这就好比别人已经有了女朋友,那我就不找女朋友了?愚蠢。当然我也得找!最近腰疼的我什么心情也没有,身体健康才是第一位。明天请一天的假,去医院看病!
Gson很早一前就听说过,可我没怎么自已研究使用过,就是因为《第一行代码》中关于Gson的一句话,让我望而止步。弱者总是畏惧未知领域,而强者总是充满冒险精神!就是这句话:“如果需要解析的是一段 JSON数组会稍微麻烦一点,我们需要借助 TypeToken将期望解析成的数据类型传入到 fromJson()方法中”。
今天用一个例子分别使用Gson和JAVA中的方法进行处理。关于Gson的详细用法,我会在后续的文章中再陈述。(没想到现在都2020年4月1号愚人节了,还是没有后续,哈哈)。
上面的废话有点多,开搞,在Android Studio中使用Gson很简单,在你的build文件中加入依赖。
implementation 'com.google.code.gson:gson:2.8.6'
- 先定义一个类
public class Person {
private String id;
private String name;
private String version;
//...
//省略getter/setter
}
Gson常用的方法有两个
//把一个对象转化成json格式的数据,这个方法有很多重载的方法
toJson(Object src);
//把json格式的数据还原成对应的对象。这个方法有很多重载方法
fromJson(String json, Class<T> classOfT)
把基本数据类型转化成json格式的数据
gson.toJson(1);//把一个int类型的数字转化为json字符串
gson.toJson(true);//把一个boolean类型的值转化为json字符串
gson.toJson(1.3f);//把一个float类型的数据转化为json字符串
gson.toJson(1.4);//把一个double类型的数据转化为json字符串
gson.toJson('a');//把一个char类型的数据转化为json字符串
gson.toJson("hello world");//把一个String转化为json字符串
//自定义一个对象。
Person person = new Person("1", "dumingwei", "2016");
gson.toJson(person);//把一个自定义的对象转化成gson字符串
注意:private transient int value3 = 3; transient 标记的变量默认情况下不会被转化成json数据
输出结果:
把基本的数据类型的json数据还原成基本数据类型
gson.fromJson("100", int.class);
gson.fromJson("1.3f", float.class);
gson.fromJson("99.99", double.class);
gson.fromJson("true", boolean.class);
gson.fromJson("\"hello world\"", String.class);
Person person = gson.fromJson("{\"id\":\"1\",\"name\":\"dumingwei\",\"version\":\"2015\"}", Person.class);
输出结果
把数组转化成json格式的数据
Gson gson = new Gson();
int[] arrayInt = {2, 3, 4, 5, 1, 6};//基本数据类型的数组
String arrayJson = gson.toJson(arrayInt);
//自定义对象的数组
Person[] arrayPerson = {new Person("1", "dumingwei", "2014"), new Person("1", "human", "2015"), new Person("1", "dumingwei", "2016")};
String arrayPersonJson = gson.toJson(arrayPerson);
输出结果
把json数据还原成数组
Gson gson = new Gson();
//还原基本数据类型数组
int[] result = gson.fromJson(arrayJson, int[].class);
for (int i : result) {
Log.e("TAG",i+" ");
}
//还原自定义对象数组
Person people[] = gson.fromJson(arrayPersonJson, Person[].class);
for (Person person : people) {
Log.e("TAG","id:" + person.getId() + ",name:" + person.getName() + ",version:" + person.getVersion() + "\n");
}
输出结果
2. 把List集合转化成json数据
Gson gson = new Gson();
List<Person> list2 = new ArrayList<>();
list2.add(new Person("1", "human", "2016"));
list2.add(new Person("2", "dumingwei", "2016"));
list2.add(new Person("3", "heima", "2016"));
list2.add(new Person("4", "hello", "2016"));
//把一个list转化成json串
String listPersonJson = gson.toJson(list2);
Log.e("TAG",listPersonJson );
输出结果:
[
{
"id": "1",
"name": "human",
"version": "2016"
},
{
"id": "2",
"name": "dumingwei",
"version": "2016"
},
{
"id": "3",
"name": "heima",
"version": "2016"
},
{
"id": "4",
"name": "hello",
"version": "2016"
}
]
注意:如果你把Log打印出来的字符串复制到java文件中是这样的:
String s="[{\"id\":\"1\",\"name\":\"human\",\"version\":\"2016\"},{\"id\":\"2\",\"name\":\"dumingwei\",\"version\":\"2016\"},{\"id\":\"3\",\"name\":\"heima\",\"version\":\"2016\"},{\"id\":\"4\",\"name\":\"hello\",\"version\":\"2016\"}]";
接下来我们试着使用Gson和Java中的方法解析这段字符串
- 使用Gson
Gson gson = new Gson();
// 借助 TypeToken将期望解析成的数据类型传入到 fromJson()方法中
List<Person> list4 = gson.fromJson(listPersonJson, new TypeToken<List<Person>>() {}.getType());
for (Person person : list4) {
//把解析出来的内容打印出来
Log.e("TAG","id:" + person.getId() + ",name:" + person.getName() + ",version:" + person.getVersion());
}
//打印结果
TAG: id:1,name:human,version:2016
TAG: id:2,name:dumingwei,version:2016
TAG: id:3,name:heima,version:2016
TAG: id:4,name:hello,version:2016
2.使用java自带的方法
List<Person>people=new ArrayList<>();
try {
JSONArray jsonArray=new JSONArray(listPersonJson);//解析的内容是一个json数组
//遍历得到jsonArray中的每一项
for (int i=0;i<jsonArray.length();i++){
JSONObject jsonObject=jsonArray.getJSONObject(i);
//解析出每一项的字段,还原成一个person
Person person=new Person(jsonObject.getString("id"),jsonObject.getString("name"),jsonObject.getString("version"));
//把person添加到people集合中
people.add(person);
}
} catch (JSONException e) {
e.printStackTrace();
}
//遍历输出集合中的每一项。得到打印结果
for (Person person : people) {
// tvResult.append("id:" + person.getId() + ",name:" + person.getName() + ",version:" + person.getVersion() + "\n");
Log.e("TAG","id:" + person.getId() + ",name:" + person.getName() + ",version:" + person.getVersion());
}
//打印结果和上面一样一样的。
TAG: id:1,name:human,version:2016
TAG: id:2,name:dumingwei,version:2016
TAG: id:3,name:heima,version:2016
TAG: id:4,name:hello,version:2016
Gson解析Json需要注意的点
- 列表元素全部为null
[null,null,null]
这样的json字符串是可以解析出列表对象的,但是列表中的每个元素都是null。
String jsonPersonList = "[null,null,null]";
List<Person> personList1 = gson.fromJson(jsonPersonList, new TypeToken<List<Person>>() {
}.getType());
Log.d(TAG, "onCreate: personList1.size = " + personList1.size());
for (Person person2 : personList1) {
//列表中的元素都为null,这里要注意判空。
//int age = person2.getAge();
}
解析出来的personList1对象
[null,null,null]
可以看到,能够解析出List<Person>
,但是列表中的每个元素都是null,使用列表中的元素的时候要注意判空。
- 列表中某些元素为null
[{"age":0,"id":"1","name":"dumingwei","version":"2016"},,]
这个Json数据中,第一个元素是正确的,但是第2个元素和第三个元素都是没有值的(逗号后面什么都没有)。这样也是可以解析出List<Person>
,但是列表中某些元素为null。
[Person{id='1', name='dumingwei', version='2016', age=0}, null, null]
列表中第二个元素和第三个元素为null,使用列表中的元素的时候要注意判空。
- 解析int类型数据
public class Person {
private String id;
private String name;
private String version;
private int age;
//...
//省略getter/setter
}
我们给Person类加一个int类型的age字段。
我们解析一段json 数据
//可以成功解析
{"age":10,"id":"1","name":"dumingwei","version":"2016"}
//可以成功解析
{"age":10.00,"id":"1","name":"dumingwei","version":"2016"}
//解析失败
{"age":10.01,"id":"1","name":"dumingwei","version":"2016"}
//可以成功解析
{"age":"10","id":"1","name":"dumingwei","version":"2016"}
//可以成功解析
{"age":"10.00","id":"1","name":"dumingwei","version":"2016"}
//解析失败
{"age":"10.11","id":"1","name":"dumingwei","version":"2016"}
注意一下几种上面json数据的区别。解析失败,是因为无法转化成int类型。
Caused by: com.google.gson.JsonSyntaxException:
java.lang.NumberFormatException: Expected an int but was 10.11 at line 1 column 15 path $.age
本篇讲的是Gson的基本用法,关于Gson的更多用法,以后有时间,有精力,我还会再写。
参考链接: