Fastjson与Gson的简单使用
Fastjson与Gson的简单使用
Fastjson
Java对象 -> Json字符串
Fastjson将对象转成Json字符串依赖于对象的get方法,以Person类为例(注意该类中没有sex属性的set、get方法,且多加一个非本类属性的getOther方法):
public class Person {
String name;
Integer age;
Integer sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getOther() {
return "测试";
}
public Person(String name, Integer age, Integer sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
测试方法:
@Test
void test1() {
Person person = new Person("coderzpw", 22, 1);
String jsonString = JSONObject.toJSONString(person);
System.out.println(jsonString);
}
输出结果:

从结果可以看出,fastjson的toJSONString方法依赖于类的get方法,而不依赖于类属性
Json字符串 -> Java对象
若存在有参构造方法,则依赖于有参构造;若无有参构造,则依赖于set方法。
存在有参构造,则依赖于有参构造
public class Person {
String name;
Integer age;
Integer sex;
public Person(String name, Integer age, Integer sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
测试方法:
@Test
void test2() {
String jsonStr = "{\"age\":22,\"name\":\"coderzpw\",\"sex\":\"1\"}";
Person person = JSONObject.parseObject(jsonStr, Person.class);
System.out.println(person);
}
输出结果:

不存在有参构造,则依赖于set方法
如下缺少sex属性的set方法
public class Person {
String name;
Integer age;
Integer sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
测试方法:
@Test
void test2() {
String jsonStr = "{\"age\":22,\"name\":\"coderzpw\",\"sex\":\"1\"}";
Person person = JSONObject.parseObject(jsonStr, Person.class);
System.out.println(person);
}
输出结果:

Json字符串 -> JSONObject对象
还是之前的JSONObject.parseObject方法,只是这次参数只需要一个json字符串即可,不需要xxx.class
@Test
void test3() {
String jsonStr = "{\"age\":22,\"name\":\"coderzpw\",\"sex\":\"1\"}";
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
System.out.println(jsonObject);
}
具体怎么操作 JSONObject对象可以看这篇文章:【fastjson对json对象的操作】
Json字符串 <-> JSONArray对象
对象集合转成 json字符串
@Test
void test1() {
Person p1 = new Person("成神苦练元歌", 18, 1);
Person p2 = new Person("小虎牙", 19, 1);
Person p3 = new Person("国服第一JAVA", 20, 1);
Person p4 = new Person("coderzpw", 22, 1);
List<Person> list = new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
String jsonString = JSONObject.toJSONString(list);
System.out.println(jsonString);
}
输出结果:

json字符串转成对象集合
@Test
void test4() {
String str = "[{\"age\":18,\"name\":\"成神苦练元歌\",\"sex\":1},{\"age\":19,\"name\":\"小虎牙\",\"sex\":1},{\"age\":20,\"name\":\"国服第一JAVA\",\"sex\":1},{\"age\":22,\"name\":\"coderzpw\",\"sex\":1}]";
// 不指定转成什么类, 最终类型是 JSONArray
JSONArray objects = JSONObject.parseArray(str);
System.out.println(objects);
// 指定xxx.class,最终转成 List<Xxx>
List<Person> persons = JSONObject.parseArray(str, Person.class);
System.out.println(persons);
}
输出结果:

FastJson序列化时"$ref":“$.a.b” ——引用类型
出现$ref的原因是多个key映射同一个引用对象
以下面这个Person类为例:
这里加了Lombok的注解,已实现set、get和构造方法
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
String name;
Integer age;
Integer sex;
Animal animal1;
Animal animal2;
Person person;
}
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Animal {
public String name;
}
测试方法:
@Test
void test1() {
Person person = new Person();
person.setName("coderzpw");
person.setAge(22);
person.setSex(1);
Animal animal = new Animal("哈士奇");
// 这里 animal1 和 animal2 指定同一个引用对象 animal
person.setAnimal1(animal);
person.setAnimal2(animal);
// person对象指向自己(直接调用JSONObject.toJSON,会出现循环引用导致占内存溢出)
person.setPerson(person);
String jsonString = JSONObject.toJSONString(person);
System.out.println(jsonString);
}
输出结果:

因为循环引用的会问题,这里如果想要直接通过 (JSONObject)JSONObject.toJSON(person)将person对象直接转成JSONObject,则会报栈内存溢出错误
@Test
void test1() {
Person person = new Person();
person.setName("coderzpw");
person.setAge(22);
person.setSex(1);
Animal animal = new Animal("哈士奇");
// 这里 animal1 和 animal2 指定同一个引用对象 animal
person.setAnimal1(animal);
person.setAnimal2(animal);
// person对象指向自己(直接调用JSONObject.toJSON,会出现循环引用导致占内存溢出)
person.setPerson(person);
JSONObject jsonObject = (JSONObject)JSONObject.toJSON(person);
System.out.println(jsonObject);
}
输出结果:

解决方案:JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(person)),先转成字符串,再转成JSONObject
@Test
void test1() {
Person person = new Person();
person.setName("coderzpw");
person.setAge(22);
person.setSex(1);
Animal animal = new Animal("哈士奇");
person.setAnimal1(animal);
person.setAnimal2(animal);
person.setPerson(person);
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(person));
System.out.println(jsonObject);
System.out.println(jsonObject.get("animal2"));
System.out.println(jsonObject.get("person"));
}
输出结果:

常见引用符文含义
“$ref”:”..” 上一级
“$ref”:”@” 当前对象,也就是自引用
“$ref”:”$” 根对象
{"$ref":"../.."} 引用父对象的父对象
“$ref”:”$.children.0” 基于路径的引用,相当于root.getChildren().get(0)
Gson
Java对象 -> Json字符串
Gson将对象转成Json字符串依赖于对象的属性(不依赖get方法),以Person类为例:
public class Person {
String name;
Integer age;
Integer sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getOther() {
return "测试";
}
public Person(String name, Integer age, Integer sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
Java对象转Json字符串:
测试方法:
@Test
void test2() {
Person person = new Person("coderzpw", 22, 1);
Gson gson = new Gson();
String jsonStr = gson.toJson(person);
System.out.println(jsonStr);
}
结果输出:

Java对象集合转Json字符串:
测试代码:
@Test
void test2() {
Person p1 = new Person("成神苦练元歌", 18, 1);
Person p2 = new Person("小虎牙", 19, 1);
Person p3 = new Person("国服第一JAVA", 20, 1);
Person p4 = new Person("coderzpw", 22, 1);
List<Person> list = new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
Gson gson = new Gson();
String jsonStr = gson.toJson(list);
System.out.println(jsonStr);
}
输出结果:

Java的Map转成Json字符串:
测试方法:
@Test
void test2() {
Map<String, Person> map = new HashMap<>();
Person p1 = new Person("成神苦练元歌", 18, 1);
Person p2 = new Person("小虎牙", 19, 1);
Person p3 = new Person("国服第一JAVA", 20, 1);
Person p4 = new Person("coderzpw", 22, 1);
map.put("p1", p1); map.put("p2", p2); map.put("p3", p3); map.put("p4", p4);
Gson gson = new Gson();
String jsonStr = gson.toJson(map);
System.out.println(jsonStr);
}
测试方法:

Json字符串 -> Java对象
测试方法:
@Test
void test2() {
String jsonStr = "{\"name\":\"成神苦练元歌\",\"age\":18,\"sex\":1}";
Gson gson = new Gson();
Person person = gson.fromJson(jsonStr, Person.class);
System.out.println(person);
}
输出结果:

Json字符串 -> List 和 Map
对于List、Set、Map这些类型,不能直接使用formJson(jsonStr, xxx.class),否则会转成Object。
可以统一写成gson.fromJson(jsonStr, new TypeToken<xxx>() {}.getType())的格式, 其中xxx用来指定集合类型。
Json字符串转成List
测试方法:
@Test
void test2() {
String jsonStr = "[{\"name\":\"成神苦练元歌\",\"age\":18,\"sex\":1},{\"name\":\"小虎牙\",\"age\":19,\"sex\":1},{\"name\":\"国服第一JAVA\",\"age\":20,\"sex\":1},{\"name\":\"coderzpw\",\"age\":22,\"sex\":1}]";
Gson gson = new Gson();
List<Person> list = gson.fromJson(jsonStr, new TypeToken<List<Person>>() {}.getType());
System.out.println(list);
}
输出结果:

Json字符串转成Map
测试方法:
@Test
void test2() {
String jsonStr = "{\"p1\":{\"name\":\"成神苦练元歌\",\"age\":18,\"sex\":1},\"p2\":{\"name\":\"小虎牙\",\"age\":19,\"sex\":1},\"p3\":{\"name\":\"国服第一JAVA\",\"age\":20,\"sex\":1},\"p4\":{\"name\":\"coderzpw\",\"age\":22,\"sex\":1}}";
Gson gson = new Gson();
Map<String, Person> map = gson.fromJson(jsonStr, new TypeToken<Map<String, Person>>() {}.getType());
System.out.println(map);
}
输出结果:
