Jackson JSON包在從物件對映到Json字串過程的迴圈依賴問題-分析與解決
提出問題
在基於Jackson類庫將物件轉化為json字串時,如果物件中存在互相依賴,則會產生無限迴圈的情況,具體情況如下:
BuyerEntity.java
@Table(name="t_buyer")
@Entity
@ToString(callSuper=true)
@Data
@EqualsAndHashCode(callSuper=false)
public class BuyerEntity extends BaseEntity {
@Column(nullable=false)
private String name;
@Column
private Integer age;
@Column(name="sex")
private Integer sex;
//@Enumerated(EnumType.ORDINAL)
@Column(nullable=false, name="gender")
@Convert(converter = GenderConverter.class)
private Gender gender = Gender.Male;
@Column
private String email;
@OneToMany(cascade= {CascadeType.ALL}, mappedBy="buyer")
private List<OrderEntity> orders;
}
OrderEntity.java
@Entity
@Table(name="t_order")
@ToString(callSuper=true)
@Data
public class OrderEntity extends BaseEntity {
//商品消費資料量
@Column
private int count;
//消費記錄的總價
@Column(name="total_fee")
private double totalFee;
//折扣率
@Column(name="discount_rate")
private double discountRate;
@ManyToOne(cascade= {CascadeType.REFRESH})
@JoinColumn(name="buyer_id", referencedColumnName="id")
private BuyerEntity buyer;
}
生成Json字串的過程如下:
BuyerEntity buyer = new BuyerEntity();
buyer.setAge(12);
buyer.setCreatedTime(new Date());
buyer.setUpdatedTime(new Date());
buyer.setEmail("123@123.cn");
buyer.setGender(Gender.Female);
buyer.setName("zhangsan");
OrderEntity order1 = new OrderEntity();
order1.setCount(12);
order1.setCreatedTime(new Date());
order1.setUpdatedTime(new Date());
order1.setTotalFee(123.3);
order1.setDiscountRate(0.80);
order1.setBuyer(buyer);
OrderEntity order2 = new OrderEntity();
order2.setCount(9);
order2.setCreatedTime(new Date());
order2.setUpdatedTime(new Date());
order2.setTotalFee(35.3);
order2.setDiscountRate(0.60);
order1.setBuyer(buyer);
List<OrderEntity> orders = Lists.newArrayList();
orders.add(order1);
orders.add(order2);
buyer.setOrders(orders);
ObjectMapper objectMapper = new ObjectMapper();
String jsonStr = objectMapper.writeValueAsString(buyer);
System.out.println(jsonStr);
上述結果資訊中則會出現如下的無限迴圈:
{"code":0,"message":"success","data":{"id":2,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"name":"zhangsan","age":12,"sex":null,"gender":"Female","email":"123@123.cn","orders":[{"id":3,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"count":12,"totalFee":123.3,"discountRate":0.8,"buyer":{"id":2,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"name":"zhangsan","age":12,"sex":null,"gender":"Female","email":"123@123.cn","orders":[{"id":3,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"count":12,"totalFee":123.3,"discountRate":0.8,"buyer":{"id":2,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"name":"zhangsan","age":12,"sex":null,"gender":"Female","email":"123@123.cn","orders":[{"id":3,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"count":12,"totalFee":123.3,"discountRate":0.8,"buyer":{"id":2,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"name":"zhangsan","age":12,"sex":null,"gender":"Female","email":"123@123.cn","orders":[{"id":3,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"count":12,"totalFee":123.3,"discountRate":0.8,"buyer":{"id":2,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"name":"zhangsan","age":12,"sex":null,"gender":"Female","email":"123@123.cn","orders":[{"id":3,"createdTime":"2019-03-19T01:30:53.123+0000","updatedTime":"2019-03-19T01:30:53.123+0000","version":0,"count":12,"totalFee":123.3,"discountRate":0.8,"
問題解決
那該問題該如何破解呢?
- 使用 @JsonManagedReference @JsonBackReference
@JsonManagedReference: 正常輸出Json的字串
@JsonBackReference: 則會忽略輸出json的字串 - @JsonIgnore: 其本身是忽略json的字串輸出的。
解決方案
於是將@JsonManagedReference 放到BuyerEntity.java中的List之上。
@JsonBackReference
@ManyToOne(cascade= {CascadeType.REFRESH})
@JoinColumn(name="buyer_id", referencedColumnName="id")
private BuyerEntity buyer;
與之相對應的是另外一個:
@JsonManagedReference
@OneToMany(cascade= {CascadeType.ALL}, mappedBy="buyer")
private List<OrderEntity> orders;
測試用例
public class JacksonCircularReferenceTest {
private ObjectMapper objectMapper = new ObjectMapper();
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void test() throws JsonProcessingException {
BuyerEntity buyer = new BuyerEntity();
buyer.setAge(12);
buyer.setCreatedTime(new Date());
buyer.setUpdatedTime(new Date());
buyer.setEmail("123@123.cn");
buyer.setGender(Gender.Female);
buyer.setName("zhangsan");
OrderEntity order1 = new OrderEntity();
order1.setCount(12);
order1.setCreatedTime(new Date());
order1.setUpdatedTime(new Date());
order1.setTotalFee(123.3);
order1.setDiscountRate(0.80);
order1.setBuyer(buyer);
OrderEntity order2 = new OrderEntity();
order2.setCount(9);
order2.setCreatedTime(new Date());
order2.setUpdatedTime(new Date());
order2.setTotalFee(35.3);
order2.setDiscountRate(0.60);
order1.setBuyer(buyer);
List<OrderEntity> orders = Lists.newArrayList();
orders.add(order1);
orders.add(order2);
buyer.setOrders(orders);
String jsonStr = objectMapper.writeValueAsString(buyer);
System.out.println(jsonStr);
}
}
參考資料
相關文章
- spring迴圈依賴解決過程&Bean的生命週期SpringBean
- Spring 迴圈依賴的三種方式(三級快取解決Set迴圈依賴問題)Spring快取
- spring解決迴圈依賴Spring
- json 物件與json 字串的區別。JSON物件字串
- Json物件與Json字串互轉JSON物件字串
- 面試題:Spring 的迴圈依賴問題面試題Spring
- c++類迴圈依賴的問題C++
- 從json-lib轉成jackson的遇到的問題JSON
- Spring怎麼解決迴圈依賴?Spring
- 三探迴圈依賴 → 記一次線上偶現的迴圈依賴問題
- Spring原始碼分析之迴圈依賴及解決方案Spring原始碼
- 【Spring】Spring中的迴圈依賴及解決Spring
- 如何解決使用JSON.stringify時遇到的迴圈引用問題JSON
- 記錄遇到的一個迴圈依賴問題
- 相容系列-JSON.parse()轉字串為json物件,解決IE7及以下不相容問題JSON字串物件
- Spring原始碼分析(三)手寫簡單的IOC容器和解決迴圈依賴問題Spring原始碼
- 再探迴圈依賴 → Spring 是如何判定原型迴圈依賴和構造方法迴圈依賴的?Spring原型構造方法
- json字串與物件互相轉換JSON字串物件
- Spring原始碼分析:Spring的迴圈依賴分析Spring原始碼
- Spring基礎系列-Spring事務不生效的問題與迴圈依賴問題Spring
- Spring如何解決迴圈依賴?Spring
- Newtonsoft.Json序列化JSON字串問題JSON字串
- fastjson: json物件,json物件陣列,javabean物件,json字串之間的相互轉化ASTJSON物件陣列JavaBean字串
- Gateway過濾器中呼叫OpenFeign時出現迴圈依賴問題Gateway過濾器
- 24--Spring解決bean之間的迴圈依賴SpringBean
- spring是如何解決迴圈依賴的?Spring
- Spring是如何解決迴圈依賴的Spring
- Spring迴圈依賴Spring
- SpringIOC迴圈依賴Spring
- 物件轉json字串的過程中對value為null的值的一些處理物件JSON字串Null
- JS json字串轉物件、物件轉字串JSON字串物件
- Spring中如何解決迴圈依賴Spring
- fastjson字串轉JSON的$ref問題ASTJSON字串
- 關於我對Spring迴圈依賴的思考Spring
- js物件轉json字串物件JSON字串
- Spring學習:簡單實現一個依賴注入和迴圈依賴的解決Spring依賴注入
- go 中的迴圈依賴Go
- Spring中的迴圈依賴Spring