怎么给客户推网站建设,罗马柱 东莞网站建设,给wordpress添加背景音乐,wordpress查看访问GSON
GSON弥补了JSON的许多不足的地方#xff0c;在实际应用中更加适用于Java开发。在这里#xff0c;我们主要讲解的是利用GSON来操作java对象和json数据之间的相互转换#xff0c;包括了常见的对象序列化和反序列化的知识。
一、前言
因为json有2种类型#xff1a;
一…GSON
GSON弥补了JSON的许多不足的地方在实际应用中更加适用于Java开发。在这里我们主要讲解的是利用GSON来操作java对象和json数据之间的相互转换包括了常见的对象序列化和反序列化的知识。
一、前言
因为json有2种类型
一种是对象object - {key:value,key:value,…} 。另一种是数组array - [value,value,…] 。
所以针对这两种类型来展开对json数据的操作。
GSON在解析json的时候大体上有2种类型一种是直接在内存中生成object或array通过手工指定key来获取值另一种是借助javabean来进行映射获取值。
二、对 json 数据进行反序列化得到java 对象
1、不借助java 类直接解析json 数据
1.1、json 是对象类型
当ajax传过来的json数据属于对象时不论这个对象简单还是复杂都可以轻松地把它们给解析出来。
ajax传过来的json数据是对象形式
var data_json {sex: 男,hobby:[baskte,tennis],introduce: {name:tom,age:23}};data: JSON.stringify(data_json),GSON解析
BufferedReader reader request.getReader();// 读取json数据StringBuffer buffer new StringBuffer();String s;while ((s reader.readLine()) ! null) {buffer.append(s);}String json buffer.toString();System.out.println(json: json); // json解析器解析json数据JsonParser parser new JsonParser();JsonElement element parser.parse(json);// json属于对象类型时if (element.isJsonObject()) { JsonObject object element.getAsJsonObject(); // 转化为对象// 1. value为string时取出stringString sex object.get(sex).getAsString(); System.out.println(sex: sex);// 2. value为array时取出arrayJsonArray hobbies object.getAsJsonArray(hobby); // for (int i 0; i hobbies.size(); i) {String hobby hobbies.get(i).getAsString();System.out.println(hobby: hobby);}// 3. value为object时取出objectJsonObject introduce object.getAsJsonObject(introduce);String name introduce.get(name).getAsString();int age introduce.get(age).getAsInt();System.out.println(name: name;age: age);}解读
很明显对于传过来的对象类型的json数据使用GSON是很方便进行解析的在得到了json数据对应的JsonObject 对象之后我们就可以很简单地进行操作了。这种方法是直接获取json中的值而没有进行java对象的还原简单情况下没有必要生成相应的javabean。
1.2、json 是数组类型
ajax传过来的json数据是数组形式
var data_json [cake,2,{brother:tom,sister:lucy},[red,orange]
];data: JSON.stringify(data_json),GSON解析
BufferedReader reader request.getReader();StringBuffer buffer new StringBuffer();String s;while ((s reader.readLine()) ! null) {buffer.append(s);}String json buffer.toString();System.out.println(json:json);// json解析器解析json数据JsonParser parser new JsonParser();JsonElement element parser.parse(json);// json属于数组类型if (element.isJsonArray()) { JsonArray array element.getAsJsonArray();// 1. value为string时取出stringString array_1 array.get(0).getAsString();System.out.println(array_1:array_1);// 2. value为int时取出intint array_2 array.get(1).getAsInt();System.out.println(array_2:array_2);// 3. value为object时取出objectJsonObject array_3 array.get(2).getAsJsonObject();String brother array_3.get(brother).getAsString();String sister array_3.get(sister).getAsString();System.out.println(brother:brother;sister:sister);// 4. value为array时取出arrayJsonArray array_4 array.get(3).getAsJsonArray();for (int i 0; i array_4.size(); i) {System.out.println(array_4.get(i).getAsString());}}解读
当json是数组类型的时候使用GSON操作和上一小节几乎差不多只不过是第一步生成的json对象是数组而已。上面2种方式解析json十分简单在日常使用中足够了。
但是对于有规律的json数据比如往往是可以映射成一个javabean对象那么我们就没有必要一个个手工取值了我们可以借助javabean配合GSON来更加快速地解析json数据。
2、借助java 类生成对应java 对象来解析数据
详细的前端json 数据可以看前面的反例以下只是使用直接的json数据进行说明。
生成对于的java对象之后就可以通过getter方法来获取相应的数据了。
通用代码
在这个方法里借助json数据来生成java对象的代码都是一致的
Gson gson new Gson();
BeanType bean gson.fronJson(jsonData, BeanType.class);2.1、 json 是对象类型
2.1.1 基本案列
json 数据
{name:tom,salary:2999}java类
public class MyEntry {private String name;private int age;public String address;public int salary;// getter、setter、toString
}java 代码
String json1 {\name\:\tom\,\salary\:2999};
Gson gson1 new Gson();
MyEntry entry1 gson1.fromJson(json1, MyEntry.class);
System.out.println(entry1.toString()); // name:tom,age:0,address:null,salary:2999解读
可以看出对于不完整的json 数据在我们映射了相应的java 类之后转化得到的java对象未赋值的字段都是默认值。这就符合java的规范和常理。
2.1.2 字段名并不一致怎么办
如果前端传过来的json 数据的key和我们java类的字段不一致就需要我们在java类中手工进行指定。
SerializedName() 注解
比如对于上面的json 数据salary 改成money 我们得到的java对象中salary 就会变成默认值0。
因此我们要使用注解:
SerializedName(money)
private String salary;SerializedName({money, salary}) // 可以有多个备选值
private String salary;2.1.3 如何限定某个字段不参加序列化或反序列化
Expose()注解
如果想要让java类的某些字段不参加序列化或反序列化可以显示来设置。如
Expose(serializefalse,deserializefalse)
private String name;上面的name 字段将不参加序列化及反序列化。
2.1.4 复合的对象怎么处理
当json 数据是对象形式时常见的value 会是一个数组或对象。如
{name: tom,age: 0,money: 2999,hobbies: [basket,tennis],collections: {2: paint,3: mouse}
}举一反三value 是数组时hobbies对应在java类中也是数组value 是对象时对应在java类中就是mapk-v对了。
因此我们可以很容易得到对应的java类
private ListString hobbies;
private MapInteger, String collections;解读 可知再复杂的json 数据我们也可以构造出对应的java类。
2.2. json 是数组类型
2.2.1 基本案例
json数据
[apple, banana, pear]显然数组在java中对应的也是数组。
java代码
String json2 [\apple\, \pear\, \banana\];
Gson gson2 new Gson();
// 传入的java类型是String[].class
String[] fruits gson2.fromJson(json2, String[].class); 2.2.2 我想用List 数组
对于上面这种简单的数组形式的json数据我们还可以反序列化为List类型的数组。因为List进行增删改都比较方便。
这里就要使用泛型了具体的泛型讲解会在下面进行说明。
String json2 [\apple\, \pear\, \banana\];
Gson gson2 new Gson();
ListString fruitList gson2.fromJson(json2, new TypeTokenListString(){}.getType());3、使用泛型
有的时候传过来的json数据在格式上是很相近的只不过某个字段的value不固定如果为此生成多个相似的java类就十分多余了。
如前端传过来的json数据主要是2类
{code:0,message:success,data:{}}{code:0,message:success,data:[]}对于字段data 有时候是对象有时候是数组。
这里我们将使用Result 来映射json数据使用MyEntry 类来映射json 数据的data 部分。这意味着对于不同的json数据我们将不再生成多个java类而是动态生成所需的java对象。
result对象
public class ResultT{public int code;public String message;public T data;// getter、setter
}3.1 data为对象的json1
{code: 0,message: success,data: [{name: tom,age: 32,address: street one,salary: 4999},{name: tom,age: 32,address: street one,salary: 4999}]
}java代码
String typeJson1 {\n \code\:0,\n \message\:\success\,\n \data\:{\n \name\:\tom\,\n \age\:32,\n \address\:\street one\,\n \salary\:4999\n }\n };
Gson typeGson1 new Gson();
// 动态生成所需的java类的类型
Type type1 new TypeTokenResultMyEntry(){}.getType();
// 动态生成java对象
ResultMyEntry result1 typeGson1.fromJson(typeJson1, type1);
System.out.println(result1);3.2 data为数值的json2
{code: 0,message: success,data: [{name: tom,age: 32,address: street one,salary: 4999},{name: lucy,age: 24,address: street three,salary: 2333}]
}java代码
String typeJson2 {\n \code\: 0,\n \message\: \success\,\n \data\: [\n {\n \name\: \tom\,\n \age\: 32,\n \address\: \street one\,\n \salary\: 4999\n },\n {\n \name\: \lucy\,\n \age\: 24,\n \address\: \street three\,\n \salary\: 2333\n }\n ]\n };
Gson typeGson2 new Gson();
// 再次动态生成java类型
Type type2 new TypeTokenResultListMyEntry(){}.getType();
// 再次动态生成java对象
ResultListMyEntry result2 typeGson2.fromJson(typeJson2, type2);
System.out.println(result2);四、java 对象序列化为json 数据
这一部分主要是讲解如何将一个java对象序列化为json数据也会涉及到如何组装这个java对象。
4.1、由具体的java类对象序列化为json 数据
我们可以直接把java对象给序列化为json数据。对于未设置的属性会采取默认值但是如果默认是null的话该属性就不会被序列化。
java类我们仍然采用的是MyEntry 类。
MyEntry entry2 new MyEntry();
entry2.setName(tom);
entry2.setSalary(2999);
ListString hobbies new ArrayList();
hobbies.add(basket);
hobbies.add(tennis);
entry2.setHobbies(hobbies);
MapInteger, String collections new HashMap();
collections.put(2, paint);
collections.put(3, mouse);
entry2.setCollections(collections);
Gson gson2 new Gson();
String json2 gson2.toJson(entry2);
System.out.println(json2);
// {name:tom,age:0,money:2999,hobbies:[basket,tennis],collections:{2:paint,3:mouse}}对于非值属性即引用属性如hobbies、collections如果没有设置值的话在序列化后的json数据中是不会出现的。而如果是值属性的话没有设置值的情况下在json数据中会是使用java中的默认值。
4.1.1 要生成对象形式的json 数据
第一种方法是上面的直接使用java类对象还可以使用生成map对象进行序列化
4.1.2 要生成数组形式的json 数据
第一种使用String[] 字符串数组来生成还可以使用List对象来序列化还可以使用Set对象来序列化
对于序列化的要求更多的情况会使用注解来选择需要/不需要进行序列化的字段。