gson创建规则以及相关对象的序列化反序列化使用方法。
主要介绍了 gson创建规则。
以及各种类型的序列化及反序列化的规则及用法,包括数组,列表,复合类等。
当json中的属性与类字段名不一样时候 @SerializedName() 注解
@SerializedName("money")
private String salary;
@SerializedName({"money", "salary"}) // 可以有多个备选值
private String salary;
@Expose()注解 如果想要让java类的某些字段不参加序列化或反序列化,可以显示来设置。如:
@Expose(serialize=false,deserialize=false)
private String name;
package jsontest;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.util.*;
public class GsonTest {
/** 查阅
Gson gson = new GsonBuilder().setLenient() // json宽松
.enableComplexMapKeySerialization() //支持Map的key为复杂对象的形式
.serializeNulls() //智能null,支持输出值为null的属性
.setPrettyPrinting()//格式化输出(序列化)
.setDateFormat("yyyy-MM-dd HH:mm:ss") //序列化日期格式化输出
.excludeFieldsWithoutExposeAnnotation() //不序列化与反序列化没有@Expose标注的字段
.disableHtmlEscaping() //默认是Gson把HTML转义的
.create();
*/
public static void main(String[] args) {
// Gson gson = new GsonBuilder().create();
Gson gson = new GsonBuilder()
//格式化输出(序列化)enableComplexMapKeySerialization() 支持Map的key为复杂对象的形式
.setPrettyPrinting()
//序列化日期格式化输出
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.create();
/**
* 序列化
*/
String jsonNumber = gson.toJson(100);
String jsonBoolean = gson.toJson(false);
String jsonString = gson.toJson("String");
/**
* 反序列化
*/
int i = gson.fromJson("100", int.class);
double d = gson.fromJson("99.99", double.class);
double d1 = gson.fromJson("\"99.99\"", double.class);
boolean b = gson.fromJson("true", boolean.class);
String str = gson.fromJson("String", String.class);
System.out.println(d1);
System.out.println(d);
User user = new User("1","wang",new Date());
String jsonStr = gson.toJson(user);
System.out.println(jsonStr);
User userk = gson.fromJson(jsonStr, User.class);
System.out.println(userk);
//包含其他对象的序列化
User user1 = new User("1", "王重阳", new Date());
User user2 = new User("2", "郭靖", new Date());
User user3 = new User("3", "黄蓉", new Date());
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
Dept dept = new Dept();
dept.setId("A001");
dept.setDeptName("研发部");
dept.setUsers(userList);
System.out.println("类内有list 序列化");
String deptstr = gson.toJson(dept);
System.out.println("类内有list<> 序列化" + deptstr);
Dept dept1 = gson.fromJson(deptstr, Dept.class);
Dept2 dept2 = new Dept2();
User[] usersArray = { user1, user2, user3 };
dept2.setId("A001");
dept2.setDeptName("研发部");
dept2.setUsers(usersArray);
//
String deptstr2 = gson.toJson(dept2);
System.out.println("类内有Array 序列化");
System.out.println("类内有Array 序列化"+deptstr2);
Dept2 dept3 = gson.fromJson(deptstr2, Dept2.class);
//
System.out.println("Array 序列化");
String ArrayUser = gson.toJson(usersArray);
System.out.println("Array 序列化"+ArrayUser);
gson.fromJson(ArrayUser,User[].class);
System.out.println("List 序列化");
String ArrayList = gson.toJson(userList);
System.out.println("List 序列化"+ArrayList);
//有问题
gson.fromJson(ArrayList,new TypeToken<List<User>>(){}.getType());
System.out.println("结束");
}
}
结果
99.99
99.99
{
"id": "1",
"name": "wang",
"birthday": "2022-07-09 12:10:08"
}
User{id='1', name='wang', birthday=Sat Jul 09 12:10:08 CST 2022}
类内有list 序列化
类内有list<> 序列化{
"id": "A001",
"deptName": "研发部",
"users": [
{
"id": "1",
"name": "王重阳",
"birthday": "2022-07-09 12:10:08"
},
{
"id": "2",
"name": "郭靖",
"birthday": "2022-07-09 12:10:08"
},
{
"id": "3",
"name": "黄蓉",
"birthday": "2022-07-09 12:10:08"
}
]
}
类内有Array 序列化
类内有Array 序列化{
"id": "A001",
"deptName": "研发部",
"users": [
{
"id": "1",
"name": "王重阳",
"birthday": "2022-07-09 12:10:08"
},
{
"id": "2",
"name": "郭靖",
"birthday": "2022-07-09 12:10:08"
},
{
"id": "3",
"name": "黄蓉",
"birthday": "2022-07-09 12:10:08"
}
]
}
Array 序列化
Array 序列化[
{
"id": "1",
"name": "王重阳",
"birthday": "2022-07-09 12:10:08"
},
{
"id": "2",
"name": "郭靖",
"birthday": "2022-07-09 12:10:08"
},
{
"id": "3",
"name": "黄蓉",
"birthday": "2022-07-09 12:10:08"
}
]
List 序列化
List 序列化[
{
"id": "1",
"name": "王重阳",
"birthday": "2022-07-09 12:10:08"
},
{
"id": "2",
"name": "郭靖",
"birthday": "2022-07-09 12:10:08"
},
{
"id": "3",
"name": "黄蓉",
"birthday": "2022-07-09 12:10:08"
}
]
结束
复合对象
{
"name": "tom",
"age": 0,
"money": 2999,
"hobbies": [
"basket",
"tennis"
],
"collections": {
"2": "paint",
"3": "mouse"
}
}
举一反三,value 是数组时(hobbies),对应在java类中也是数组;value 是对象时,对应在java类中就是map(k-v对)了。
因此,我们可以很容易得到对应的java类:
private List<String> hobbies;
private Map<Integer, String> collections;
泛型
有的时候,传过来的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 Result<T>{
public int code;
public String message;
public T data;
// getter、setter
}
data为对象的json1:
{
"code": 0,
"message": "success",
"data":
{
"name": "tom",
"age": 32,
"address": "street one",
"salary": 4999
}
}
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 TypeToken<Result<MyEntry>>(){}.getType();
// 动态生成java对象
Result<MyEntry> result1 = typeGson1.fromJson(typeJson1, type1);
System.out.println(result1);
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
}
]
}
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 TypeToken<Result<List<MyEntry>>>(){}.getType();
// 再次动态生成java对象
Result<List<MyEntry>> result2 = typeGson2.fromJson(typeJson2, type2);
System.out.println(result2);
直接解析json
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时,取出string
String sex = object.get("sex").getAsString(); System.out.println("sex:" + sex);
// 2. value为array时,取出array
JsonArray 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时,取出object
JsonObject 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)。
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时,取出string
String array_1 = array.get(0).getAsString();
System.out.println("array_1:"+array_1);
// 2. value为int时,取出int
int array_2 = array.get(1).getAsInt();
System.out.println("array_2:"+array_2);
// 3. value为object时,取出object
JsonObject 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时,取出array
JsonArray 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数据。