我是靠谱客的博主 英勇皮卡丘,最近开发中收集的这篇文章主要介绍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,"

问题解决

那该问题该如何破解呢?

  1. 使用 @JsonManagedReference @JsonBackReference
    @JsonManagedReference: 正常输出Json的字符串
    @JsonBackReference: 则会忽略输出json的字符串
  2. @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);
	}
}

参考资料

  1. https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion

最后

以上就是英勇皮卡丘为你收集整理的Jackson JSON包在从对象映射到Json字符串过程的循环依赖问题-分析与解决的全部内容,希望文章能够帮你解决Jackson JSON包在从对象映射到Json字符串过程的循环依赖问题-分析与解决所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部