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 迴圈依賴的三種方式(三級快取解決Set迴圈依賴問題)Spring快取
- spring迴圈依賴解決過程&Bean的生命週期SpringBean
- spring解決迴圈依賴Spring
- 面試題:Spring 的迴圈依賴問題面試題Spring
- c++類迴圈依賴的問題C++
- 解決rpm包迴圈依賴
- 關於 OkHttp 依賴衝突問題的解決過程HTTP
- json 物件與json 字串的區別。JSON物件字串
- Json物件與Json字串互轉JSON物件字串
- saltstack對遞迴依賴條件(死迴圈依賴)的處理遞迴
- Spring原始碼分析之迴圈依賴及解決方案Spring原始碼
- json字串與json物件簡單介紹JSON字串物件
- 【Spring】Spring中的迴圈依賴及解決Spring
- 再探迴圈依賴 → Spring 是如何判定原型迴圈依賴和構造方法迴圈依賴的?Spring原型構造方法
- Spring原始碼分析(三)手寫簡單的IOC容器和解決迴圈依賴問題Spring原始碼
- Spring如何解決迴圈依賴?Spring
- go 中的迴圈依賴Go
- 如何解決使用JSON.stringify時遇到的迴圈引用問題JSON
- DDD領域層與基礎設施層迴圈依賴問題
- 從json-lib轉成jackson的遇到的問題JSON
- 探索 JavaScript 中的依賴管理及迴圈依賴JavaScript
- 24--Spring解決bean之間的迴圈依賴SpringBean
- Gateway過濾器中呼叫OpenFeign時出現迴圈依賴問題Gateway過濾器
- SpringIOC迴圈依賴Spring
- Spring迴圈依賴Spring
- 淺談迴圈依賴
- spring是如何解決迴圈依賴的?Spring
- Spring是如何解決迴圈依賴的Spring
- Spring基礎系列-Spring事務不生效的問題與迴圈依賴問題Spring
- Spring原始碼分析:Spring的迴圈依賴分析Spring原始碼
- Spring中如何解決迴圈依賴Spring
- 相容系列-JSON.parse()轉字串為json物件,解決IE7及以下不相容問題JSON字串物件
- json字串與物件互相轉換JSON字串物件
- js字串與json物件處理字串JSON物件
- 呼叫者許可權過程對OWNER物件的依賴物件
- Spring學習:簡單實現一個依賴注入和迴圈依賴的解決Spring依賴注入
- 關於我對Spring迴圈依賴的思考Spring
- Spring中的迴圈依賴Spring