在开发的过程中遇到省市县树的转json问题,接下来就给出遇到的问题及解决方案:
由于对象中存在双向引用导致的无限递归,从而在转json的过程中产生溢出,解决的方案如下通过加注解的方式来避免溢出。
jackson中的@JsonBackReference和@JsonManagedReference,以及@JsonIgnore均是为了解决对象中存在双向引用导致的无限递归(infinite recursion)问题,这些标注均可用在属性或对应的get、set方法中。
@JsonBackReference和@JsonManagedReference:这两个标注通常配对使用,通常用在父子关系中。 @JsonBackReference标注的属性在序列化(serialization,即将对象转换为json数据)时,会被忽略(即结果中的json数据不包含该属性的内容)。
@JsonManagedReference标注的属性则会被序列化。在序列化时,@JsonBackReference的作用相当于@JsonIgnore,此时可以没有@JsonManagedReference。但在反序列化(deserialization,即json数据转换为对象)时,如果没有@JsonManagedReference,则不会自动注入
@JsonBackReference标注的属性(被忽略的父或子);如果有@JsonManagedReference,则会自动注入自动注入@JsonBackReference标注的属性。
@JsonIgnore:直接忽略某个属性,以断开无限递归,序列化或反序列化均忽略。当然如果标注在get、set方法中,则可以分开控制,序列化对应的是get方法,反序列化对应的是set方法。在父子关系中,当反序列化时,@JsonIgnore不会自动注入被忽略的属性值(父或子),这是它跟@JsonBackReference和@JsonManagedReference最大的区别。
以下为测试代码:
AreaVO类
public class AreaVO implements Serializable {
private Integer areaId; /* 索引ID */
private String areaName; /* 地区名称 */
private Integer areaParentId; /* 地区父ID */
private Boolean areaSort; /* 排序 */
private Integer areaDeep; /* 地区深度,从1开始 */
private String areaRegion; /* 大区名称 */
private AreaVO parentRegion; /* 父节点 */
private ArrayList childRegions = new ArrayList<>(); /* zhua */
private String warehouseName; /* 仓库名称*/
// Constructor
public AreaVO() {
}
@JsonManagedReference
public ArrayList getChildRegions() {
return childRegions;
}
@JsonManagedReference
public void setChildRegions(ArrayList childRegions) {
this.childRegions = childRegions;
}
@JsonBackReference
public AreaVO getParentRegion() {
return parentRegion;
}
@JsonBackReference
public void setParentRegion(AreaVO parentRegion) {
this.parentRegion = parentRegion;
}
public String getWarehouseName() {
return warehouseName;
}
public void setWarehouseName(String warehouseName) {
this.warehouseName = warehouseName;
}
/**
* full Constructor
*/
public AreaVO(Integer areaId, String areaName, Integer areaParentId, Boolean areaSort, Integer areaDeep, String areaRegion) {
this.areaId = areaId;
this.areaName = areaName;
this.areaParentId = areaParentId;
this.areaSort = areaSort;
this.areaDeep = areaDeep;
this.areaRegion = areaRegion;
}
public Integer getAreaId() {
return areaId;
}
public void setAreaId(Integer areaId) {
this.areaId = areaId;
}
public String getAreaName() {
return areaName;
}
public void setAreaName(String areaName) {
this.areaName = areaName;
}
public Integer getAreaParentId() {
return areaParentId;
}
public void setAreaParentId(Integer areaParentId) {
this.areaParentId = areaParentId;
}
public Boolean getAreaSort() {
return areaSort;
}
public void setAreaSort(Boolean areaSort) {
this.areaSort = areaSort;
}
public Integer getAreaDeep() {
return areaDeep;
}
public void setAreaDeep(Integer areaDeep) {
this.areaDeep = areaDeep;
}
public String getAreaRegion() {
return areaRegion;
}
public void setAreaRegion(String areaRegion) {
this.areaRegion = areaRegion;
}
@Override
public String toString() {
return "AreaVO [" + "areaId=" + areaId + ", areaName=" + areaName + ", areaParentId=" + areaParentId + ", areaSort=" + areaSort + ", areaDeep=" + areaDeep + ", areaRegion=" + areaRegion + "]";
}
}
public class test {
// @JsonIgnore
public static void main(String[] args) {
JsonResult> jsonResult = new JsonResult>();
JsonResult jsonResult1 = new JsonResult();
List areaVOs=new ArrayList<>();
ArrayList areaVOs1=new ArrayList<>();
ArrayList areaVOs2=new ArrayList<>();
ArrayList areaVOs3=new ArrayList<>();
AreaVO areaVO=new AreaVO();
AreaVO areaVO1=new AreaVO();
AreaVO areaVO2=new AreaVO();
AreaVO areaVO3=new AreaVO();
areaVO.setAreaId(1);
areaVO.setAreaName("北京");
areaVO.setAreaParentId(0);
areaVO.setAreaSort(true);
areaVO.setAreaDeep(1);
areaVO.setAreaRegion("华北");
areaVO.setParentRegion(null);
areaVO1.setAreaId(36);
areaVO1.setAreaName("北京市");
areaVO1.setAreaParentId(1);
areaVO1.setAreaSort(true);
areaVO1.setAreaDeep(2);
areaVO1.setAreaRegion("华北");
areaVO1.setParentRegion(areaVO);
areaVO2.setAreaId(38);
areaVO2.setAreaName("西城区");
areaVO2.setAreaParentId(36);
areaVO2.setAreaSort(true);
areaVO2.setAreaDeep(3);
areaVO2.setAreaRegion("华北");
areaVO2.setParentRegion(areaVO1);
areaVO3.setAreaId(54);
areaVO3.setAreaName("延庆县");
areaVO3.setAreaParentId(36);
areaVO3.setAreaSort(true);
areaVO3.setAreaDeep(3);
areaVO3.setAreaRegion("华北");
areaVO3.setParentRegion(areaVO1);
areaVOs2.add(areaVO2);
areaVO1.setChildRegions(areaVOs2);
areaVOs3.add(areaVO3);
areaVO1.setChildRegions(areaVOs3);
areaVOs1.add(areaVO1);
areaVO.setChildRegions(areaVOs1);
areaVOs.add(areaVO);
jsonResult.setMsg("查询单个收货地址成功!");
jsonResult.setStatus("0");
jsonResult.setData(areaVOs);
System.out.println("-===" + jsonResult.getData());
System.out.println(JsonMapper.jsonMapper().toJson(jsonResult));
}
}
{
"status":"0",
"msg":"查询单个收货地址成功!",
"data":[
{
"areaId":1,
"areaName":"北京",
"areaParentId":0,
"areaSort":true,
"areaDeep":1,
"areaRegion":"华北",
"childRegions":[
{
"areaId":36,
"areaName":"北京市",
"areaParentId":1,
"areaSort":true,
"areaDeep":2,
"areaRegion":"华北",
"childRegions":[
{
"areaId":54,
"areaName":"延庆县",
"areaParentId":36,
"areaSort":true,
"areaDeep":3,
"areaRegion":"华北",
"childRegions":[
],
"warehouseName":null
}
],
"warehouseName":null
}
],
"warehouseName":null
}
]
}
以上问题就ok啦!