Could not write JSON: Infinite recursion (StackOverflowError) (through reference

85 篇文章 0 订阅
19 篇文章 0 订阅

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最大的区别。 

示例测试代码(注意反序列化后的TreeNode[readValue]的children里的parent): 
TreeNode.java 

    import java.util.ArrayList;  
    import java.util.List;  
      
    import org.codehaus.jackson.annotate.JsonBackReference;  
    import org.codehaus.jackson.annotate.JsonManagedReference;  
      
    public class TreeNode {  
        String name;  
        @JsonBackReference  
    //  @JsonIgnore  
        TreeNode parent;  
        @JsonManagedReference  
        List<TreeNode> children;  
      
        public TreeNode() {  
        }  
      
        public TreeNode(String name) {  
            this.name = name;  
        }  
      
        public String getName() {  
            return name;  
        }  
      
        public void setName(String name) {  
            this.name = name;  
        }  
      
        public TreeNode getParent() {  
            return parent;  
        }  
      
        public void setParent(TreeNode parent) {  
            this.parent = parent;  
        }  
      
        public List<TreeNode> getChildren() {  
            return children;  
        }  
      
        public void setChildren(List<TreeNode> children) {  
            this.children = children;  
        }  
      
        public void addChild(TreeNode child) {  
            if (children == null)  
                children = new ArrayList<TreeNode>();  
            children.add(child);  
        }  
    }  

 

JsonTest.java 

    import java.io.IOException;  
      
    import org.codehaus.jackson.JsonGenerationException;  
    import org.codehaus.jackson.map.JsonMappingException;  
    import org.codehaus.jackson.map.ObjectMapper;  
    import org.junit.AfterClass;  
    import org.junit.BeforeClass;  
    import org.junit.Test;  
      
    public class JsonTest {  
        static TreeNode node;  
      
        @BeforeClass  
        public static void setUp() {  
            TreeNode node1 = new TreeNode("node1");  
            TreeNode node2 = new TreeNode("node2");  
            TreeNode node3 = new TreeNode("node3");  
            TreeNode node4 = new TreeNode("node4");  
            TreeNode node5 = new TreeNode("node5");  
            TreeNode node6 = new TreeNode("node6");  
      
            node1.addChild(node2);  
            node2.setParent(node1);  
            node2.addChild(node3);  
            node3.setParent(node2);  
            node2.addChild(node4);  
            node4.setParent(node2);  
            node3.addChild(node5);  
            node5.setParent(node3);  
            node5.addChild(node6);  
            node6.setParent(node5);  
      
            node = node3;  
        }  
      
        @Test   
        public void test() throws JsonGenerationException, JsonMappingException, IOException {  
            ObjectMapper mapper = new ObjectMapper();  
            String json = mapper.writeValueAsString(node);  
            System.out.println(json);  
            TreeNode readValue = mapper.readValue(json, TreeNode.class);  
            System.out.println(readValue.getName());  
        }  
      
        @AfterClass  
        public static void tearDown() {  
            node = null;  
        }  
    }  

 参考: 
http://wiki.fasterxml.com/JacksonFeatureBiDirReferences  
jira: http://jira.codehaus.org/browse/JACKSON-235  

备注: 
jackson版本:1.9.9 

似乎jackson从2.0开始可以通过@JsonIdentityInfo解决无限递归的问题,但本人没验证。 

有兴趣还可以研究研究这篇文章里的方式: 

http://www.linuxso.com/architecture/26599.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值