@JsonIgnore 与 @JsonProperty
问题描述
在前后端分离的Web项目中,前端用的是Ant Designer,后端用Spring MVC。要求后端实体对象序列化为Json数据时忽略掉某属性,而在前端发送Json数据到后端反序列化为实体对象时不忽略掉该属性。
@ManyToOne 和 @OneToMany
对于具有一对多关系的两个实体订单表Order
和订单条目表OrderItem
,OrderItem
中会有属性order
引用,多个订单条目对应一个订单,通过@ManyToOne
映射数据库的外键关系:
@Entity
@Table(name="order_item")
public class OrderItem implements java.io.Serializable{
@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name = "order_id")
public Order getOrder() {
return this.order;
}
}
而Order
中会有属性items
引用多个订单条目,通过@OneToMany
映射数据库一对多关系:
@Entity
@Table(name="order")
public class Order implements java.io.Serializable{
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="order")
public Set<OrderItem> getItems() {
return this.items;
}
}
这里使用
mappedBy
而不是@JoinColumn
来维护一对多关系,可以参考博客 hibernate基于注解的维护权反转:@OneToMany(mappedBy=)
@JsonIgnre
当前端向后端请求订单或订单条目的详情信息时,后端将实体对象序列化为Json数据传给前端,因为Order
和OrderItem
之间有循环引用关系,所以序列化时会报错,前端无法获取数据。
解决办法便是打破循环引用,可以使用@JsonIgnore
使Order实体序列化为Json数据时,忽略掉items
属性,这里从开发习惯上一般忽略一对多的关系,获取订单条目另写接口。而多对一关系则不需要忽略,可以在返回订单条目信息时直接返回对应订单信息。
JsonIgnore
属性可以使用在属性或Getter
方法上,使Java对象序列化为Json数据时忽略此属性。
采用以上方法,可以解决前端获取后端数据的问题,但对于另一个需求,创建订单接口,前端按照后端订单实体的格式包装Json数据传给后端,反序列化为Java对象,再保存到数据库中。订单条目信息保存在订单Json数据的items
属性中,但在使用@JsonIgnore
后反序列化时该属性也会被忽略,导致后端无法获取前端Json数据的items
属性值。
@JsonProperty
后来经过查询,我们发现可以采用如下方法解决:
- 在
Getter
方法上使用@JsonIgnore
属性,使Java对象序列化时忽略掉该属性,不传给前端; - 在
Setter
方法上使用JsonProperty
属性,使Json数据反序列化为Java对象时不忽略该属性,正常获取该属性值。
修改后的代码如下:
@Entity
@Table(name="order")
public class Order implements java.io.Serializable{
@JsonIgnore
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="order")
public Set<OrderItem> getItems() {
return this.items;
}
@JsonProperty
public void setItems(Set<OrderItem> items){
this.items = items;
}
}
参考资料
[1] @OneToMany、@ManyToOne以及@ManyToMany讲解 https://www.cnblogs.com/yinchuan/p/6052507.html
[2] hibernate基于注解的维护权反转:@OneToMany(mappedBy=) http://www.cnblogs.com/chiangchou/p/mappedBy.html
[3] Annotation Type JsonIgnore https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonIgnore.html