Gson
解决循环引用问题
第一种:在需要转的属性上面加@Expose
注解
@Test
public void demo21(){
GsonBuilder gsonBuilder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation();
Gson gson = gsonBuilder.create();
Person person = new Person();
Student student = new Student();
person.setStudent(student);
student.setPerson(person);
String s = gson.toJson(student);
System.out.println(s);
}
package com.nyh.json;
import com.google.gson.annotations.Expose;
import com.nyh.reflect.Student;
/**
* @author nyh
* @create 2019-01-23 16:26
**/
public class Person {
@Expose
String name;
Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.nyh.reflect;
import com.google.gson.annotations.Expose;
import com.nyh.json.Person;
/**
* @author nyh
* @create 2019-01-23 10:41
**/
public class Student {
@Expose
private String name;
@Expose
private int age;
@Expose
String PhoneNumber;
@Expose
int id;
@Expose
Person person;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public Student() {
}
public Student(String name, int age, String phoneNumber, int id) {
this.name = name;
this.age = age;
this.PhoneNumber = phoneNumber;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPhoneNumber() {
return PhoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
PhoneNumber = phoneNumber;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", PhoneNumber='" + PhoneNumber + '\'' +
", id=" + id +
'}';
}
}
第二个办法:在不需要转的属性前面用transient
(瞬态)
public void demo21(){
// GsonBuilder gsonBuilder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation();
// Gson gson = gsonBuilder.create();
Person person = new Person();
Student student = new Student();
person.setStudent(student);
student.setPerson(person);
String s = gson.toJson(student);
System.out.println(s);
}
transient 会阻止序列化
transient Student student;
public class TestJson {
Gson gson = null;
@Before
public void before(){
gson = new Gson();
}
@Test
public void demo1(){
Person person = new Person();
person.setAge(18);
person.setName("东东");
String s = gson.toJson(person);
System.out.println(s);
}
@Test
public void demo2(){
Person person = gson.fromJson("{\"name\":\"东东\",\"age\":18}", Person.class);
System.out.println(person);
}
@Test
public void demo3(){
Person person = new Person();
person.setName("小龙");
person.setAge(15);
Student student = new Student();
student.setNumber("123456");
person.setStudent(student);
String s = gson.toJson(person);
System.out.println(s);
}
@Test
public void demo4() {
Person person = gson.fromJson("{\"name\":\"小龙\",\"age\":15,\"student\":{\"number\":\"123456\"}}", Person.class);
System.out.println(person);
}
/**
* 解决循环引用
* 两个方法
* 第一个注解
* @Expose 代表属性需要转Json(排除没有公开注释的字段)
* 创建Gson对象需要用 Gson g = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
* 第二种方式
* 在不需要转的前面加瞬态关键字 Transient
* 创建Gson 需要用 Gson g = new Gson();
*/
@Test
public void demo5() throws Exception {
//excludeFieldsWithoutExposeAnnotation 过滤不带注解的字段
// GsonBuilder gsonBuilder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation();
// Gson gson = gsonBuilder.create();
Student student = new Student();
student.setNumber("123");
Person person = new Person();
person.setStudent(student);
person.setAge(18);
person.setName("小小");
student.setPerson(person);
String s = gson.toJson(person);
System.out.println(s);
}
@Test
public void demo6() throws Exception {
List<String> lists = new ArrayList<>();
lists.add("a");
lists.add("b");
lists.add("c");
String s = gson.toJson(lists);
System.out.println(s);
}
@Test
public void demo7(){
List list = gson.fromJson("[\"a\",\"b\",\"c\"]", List.class);
System.out.println(list);
}
@Test
public void demo8() throws Exception {
Set<String> sets = new HashSet<>();
sets.add("a");
sets.add("b");
sets.add("c");
String s = gson.toJson(sets);
System.out.println(s);
}
@Test
public void demo9(){
Set sets = gson.fromJson("[\"a\",\"b\",\"c\"]", Set.class);
System.out.println(sets);
}
@Test
public void demo91(){
Map<String,String> maps = new HashMap<>();
maps.put("1","a");
maps.put("2","b");
maps.put("3","c");
String s = gson.toJson(maps);
System.out.println(s);
}
@Test
public void demo92(){
Map map = gson.fromJson("{\"1\":\"a\",\"2\":\"b\",\"3\":\"c\"}", Map.class);
System.out.println(map);
}
@Test
public void demo93(){
List<Student> students = new ArrayList<>();
students.add(new Student("123"));
students.add(new Student("456"));
String s = gson.toJson(students);
System.out.println(s);
}
@Test
public void demo94(){
List<Student> list = gson.fromJson("[{\"number\":\"123\"},{\"number\":\"456\"}]", new TypeToken<List<Student>>(){}.getType());
System.out.println(list.get(0).getNumber());
}
}
FastJson
public class TestPerson {
@Test
public void demo1(){
Person person = new Person();
person.setAge(30);
person.setName("小李");
String s = JSON.toJSONString(person);
System.out.println(s);
}
@Test
public void demo2(){
Person person = JSON.parseObject("{\"age\":30,\"name\":\"小李\"}", Person.class);
System.out.println(person);
}
/**
* 循环引用
*/
@Test
public void demo4(){
List<Person> lists = new ArrayList<Person>();
Person person = new Person();
person.setAge(11);
person.setName("小华");
lists.add(person);
lists.add(person);
lists.add(person);
/*
[{"age":11,"name":"小华"},{"$ref":"$[0]"},{"$ref":"$[0]"}] 发生了循环引用的问题
SerializerFeature.DisableCircularReferenceDetect 解决循环引用(禁用循环引用检测)
加上了这个属性后就不会出现上面这种情况了
[{"age":11,"name":"小华"},{"age":11,"name":"小华"},{"age":11,"name":"小华"}]
*/
String s1 = JSON.toJSONString(lists,SerializerFeature.DisableCircularReferenceDetect);
System.out.println(s1);
}
@Test
public void demo3(){
Person person = new Person();
Animal animal = new Animal();
person.setName("嘻嘻");
person.setAge(11);
animal.setColor("red");
animal.setName("小黑");
animal.setPerson(person);
person.setAnimal(animal);
/**
* 这里也是循环引用问题
* 用以下方式解决:
// 代表次属性不去转json
@JSONField(serialize = false)
private Person person;
*/
String s = JSON.toJSONString(person,SerializerFeature.DisableCircularReferenceDetect);
System.out.println(s);
}
@Test
public void demo5(){
List<String> lists = new ArrayList<String>();
lists.add("a");
lists.add("b");
lists.add("c");
String s = JSON.toJSONString(lists);
System.out.println(s);
}
@Test
public void demo6(){
// List<String> strings = JSON.parseObject("[\"a\",\"b\",\"c\"]", new TypeReference<List<String>>() {
// });
Set list = JSON.parseObject("[\"a\",\"b\",\"c\"]", Set.class);
System.out.println(list);
}
@Test
public void demo7(){
Map<String,String> maps = new HashMap<>();
maps.put("1","a");
maps.put("2","b");
String s = JSON.toJSONString(maps);
System.out.println(s);
}
@Test
public void demo8(){
Map map = JSON.parseObject("{\"1\":\"a\",\"2\":\"b\"}", Map.class);
System.out.println(map);
}
@Test
public void demo(){
List<Person> lists = new ArrayList<>();
Person person = new Person();
person.setName("大佬");
person.setAge(50);
lists.add(person);
String s = JSON.toJSONString(lists);
System.out.println(s);
}
@Test
public void demo9(){
/*
如果不用 TypeReference ,只能获取对象,对象里面的属性是拿不到的
*/
List<Person> people = JSON.parseObject("[{\"age\":50,\"name\":\"大佬\"}]",new TypeReference<List<Person>>(){});
System.out.println(people.get(0).getAge());
}
}