@JsonManagedReference
、@JsonBackReference
也能处理循环引用,它们是成对使用的:
-
@JsonManagedReference
:被其注解的属性可正常序列化。 -
@JsonBackReference
:被其注解的属性序列化时会被忽略掉,且只能用于普通 bean,不能是集合、Map、数组、枚举。
与 @JsonIdentityInfo
的不同之处:
@JsonIdentityInfo
会序列化对象标识符@JsonManagedReference
、@JsonBackReference
会直接忽略掉属性。@JsonIdentityInfo
能解决一对一、一对多、多对多的循环引用,但@JsonManagedReference
、@JsonBackReference
无法解决多对多的循环引用,因为@JsonBackReference
不能用于集合
Example
POJOs
public class Customer {
private int id;
private String name;
@JsonManagedReference
private Order order;
...
}
public class Order {
private int orderId;
private List<Integer> itemIds;
@JsonBackReference
private Customer customer;
...
}
序列化、反序列化
public class ExampleMain {
public static void main(String[] args) throws IOException {
Order order = new Order();
order.setOrderId(1);
order.setItemIds(List.of(10, 30));
Customer customer = new Customer();
customer.setId(2);
customer.setName("Peter");
customer.setOrder(order);
order.setCustomer(customer);
System.out.println(customer);
System.out.println("-- serializing --");
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(customer);
System.out.println(s);
System.out.println("-- deserializing --");
Customer customer2 = om.readValue(s, Customer.class);
System.out.println(customer2);
}
}
Customer 的属性 order 正常序列化了,但 Order 的 customer 属性被忽略了:
Customer{id=2, name='Peter', order=Order{id=1, itemIds=[10, 30]}}
-- serializing --
{"id":2,"name":"Peter","order":{"orderId":1,"itemIds":[10,30]}}
-- deserializing --
Customer{id=2, name='Peter', order=Order{id=1, itemIds=[10, 30]}}
涉及集合的循环引用
POJOs
public class Dept {
private int deptId;
@JsonManagedReference
List<Employee> employees;
private String name;
...
}
序列化、反序列化
public class Employee {
private int empId;
@JsonBackReference
private Dept dept;
private String name;
...
}
public class ExampleMain2 {
public static void main(String[] args) throws IOException {
Employee emp1 = new Employee();
emp1.setEmpId(1);
emp1.setName("Tina");
Employee emp2 = new Employee();
emp2.setEmpId(2);
emp2.setName("Joe");
Dept dept = new Dept();
dept.setName("IT");
dept.setDeptId(3);
dept.setEmployees(List.of(emp1, emp2));
System.out.println("-- before serializing dept --");
System.out.println(dept);
System.out.println("-- json string after serializing --");
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(dept);
System.out.println(s);
System.out.println("-- deserializing --");
Dept dept1 = om.readValue(s, Dept.class);
System.out.println(dept1);
}
}
-- before serializing dept --
Dept{deptId=3, employees=[Employee{empId=1, deptId=3, name='Tina'}, Employee{empId=2, deptId=3, name='Joe'}], name='IT'}
-- json string after serializing --
{"deptId":3,"employees":[{"empId":1,"name":"Tina"},{"empId":2,"name":"Joe"}],"name":"IT"}
-- deserializing --
Dept{deptId=3, employees=[Employee{empId=1, deptId=3, name='Tina'}, Employee{empId=2, deptId=3, name='Joe'}], name='IT'}
原文链接
Jackson JSON - Using @JsonManagedReference and @JsonBackReference for circular references