`
zzc1684
  • 浏览: 1232376 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

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

阅读更多

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

分享到:
评论

相关推荐

    解决返回JSON报错:HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowE

    然而,当出现"HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError)"这样的错误时,意味着在序列化过程中遇到了无限递归的问题。这个问题通常是由于对象之间的引用循环...

    2022最新版:INFINITE V3.4.4主题:多用途WordPress主题.rar

    标题"2022最新版:INFINITE V3.4.4主题:多用途WordPress主题.rar"表明我们正在讨论的是一个针对WordPress平台的网站主题,名为INFINITE,其版本号为V3.4.4。这个主题被称为“多用途”,意味着它设计得非常灵活,...

    Infinite.js:Infinite.js

    Infinite.js // Infinite.js $('.infinite-js').InfiniteJS({ debug: true, limit: { start: 0, total: 10, items: 10, }, repeat: { finish: 10, loadMore: 2, showLoadMore: true, }, navSelector : ...

    flutter_infinite_listview:Flutter Infinite ListView-具有可以在两个方向上无限滚动的项目的ListView。 维护者

    颤振无限ListView 具有可以在两个方向上无限滚动的项目的ListView。 快速使用 将您现有的ListView替换为InfiniteListView 。 由于其无限的性质,必须使用构建器模式。 例子 错误/请求 如果您遇到任何问题,请随时...

    The effect of reference choices on the spatio-temporal analysis of brain evoked potentials: the use of infinite reference

    ### 参考选择对脑诱发电位时空分析的影响:无限参考的应用 #### 摘要与背景 本文探讨了在脑诱发电位(Evoked Potentials, EPs)特别是体感诱发电位(Somatosensory Evoked Potentials, SEPs)的研究中,不同参考点...

    使用Element的InfiniteScroll 无限滚动组件报错的解决

    TypeError: Failed to execute ‘observe’ on ‘MutationObserver’: parameter 1 is not of type ‘Node’ InfiniteScroll的更多用法element官网 二、解决办法 给需要使用 InfiniteScroll 的元素或者它的父级...

    infinitescroll+imagesLoaded+Masonry.zip

    - **data.json**:这是提供给 Infinitescroll 加载的 JSON 数据,通常包含要显示的项的信息,如图片链接、标题等。 - **readme.txt**:这是一个简短的说明文件,可能包含了关于如何运行和理解项目的指导。 - **css**...

    Infinite-Campus-SQL:Infinite Campus 的 SQL (SQL Server) 脚本存储库

    Infinite-Campus-SQL 这是 Infinite Campus 的 SQL (SQL Server) 脚本存储库。 这里的想法是,为公共或共享功能重新发明轮子并不是对学区资源的有效利用。 鼓励K12学区分享! Infinite Campus 还有一个专门讨论报告...

    infinite-swipe:Infinite Swipe 是一个简单的滑动库,可用于桌面和移动设备

    无限滑动 Infinite Swipe 是一个简单的滑动库,可用于桌面和移动设备。这个怎么运作将目标放置在显示 UI 的舞台上。 如果target有N个页面,target应该是stage的N倍。 bower install infinite-swipe很简单的例子首先...

    finite:Infinite 的新回购!

    宝可梦对决 导航:| 服务器存储库| 介绍 这是可梦对战网站游戏服务器的源代码。 Pokémon Showdown 模拟了迄今为止所有游戏中的单打、双打和三打战斗(第 1 代到第 6 代)。 此存储库包含设置您自己的 Pokémon ...

    principals-library:Infinite Babel的主要投资者图书馆

    而"Infinite Babel"在此可能是对这个概念的现代化解读,可能是一个数字平台或者项目,旨在汇聚海量的信息和知识资源。 "主要投资者图书馆"则暗示了这是一个由投资者支持的项目,可能是一个在线平台或者数据库,为...

    jquery infinite-carousel插件

    **jQuery Infinite Carousel插件详解** jQuery Infinite Carousel是一款广泛使用的JavaScript插件,专为网页设计师和开发者设计,旨在实现无限轮播的图片或内容展示。它以其简洁、高效和高度可定制性著称,使得在...

    Ignite:Infinite Red 的前沿 React Native 项目样板-开源

    这是 Infinite Red 团队日常用于构建客户端应用程序的 React Native 样板。 使用 Ignite 的开发人员报告说,从 React Native 项目开始,它平均为他们节省了两到四个星期的时间! Ignite 应用程序包括开箱即用的坚如...

    无限绘画-Infinite-Painter-4.0.9

    无限绘画:Infinite Painter APK名称:com.brakefield.painter 最新版本:4.0.9支持ROM:3.0及更高版本 界面语言:简体中文 软件大小:17.55 M 开发者:Sean Brakefield Infinite Painter是一款轻量级的绘画工具,...

    jquery.infinitescroll滑动加载更多

    `jQuery.InfiniteScroll`是一个流行的JavaScript插件,用于实现网页内容的无限滚动效果。这个插件主要用于提升用户体验,当用户滚动页面到底部时,它会自动加载更多内容,无需手动点击“加载更多”按钮。这种技术常...

    Rasa.NET:Infinite Rasa项目的AC#版本

    Rasa.NET .NET Core上运行的游戏的游戏和身份验证服务器的AC#实现。在你开始之前该项目正在开发中,尚未完成。 您可能无法以任何身份玩游戏。 有关最新信息,我们建议聊天室。如何使用此代码在运行游戏之前,有一些...

    infinitescroll的下拉刷新的例子

    Infinitescroll是一种常见的网页滚动加载技术,常用于社交媒体、新闻网站和电子商务平台,以便在用户滚动页面时无缝地加载更多内容,而无需点击“加载更多”或分页按钮。这种用户体验可以提升用户满意度,因为他们...

    jquery.infinitescroll.js演示示例以及常用参数

    **jQuery Infinite Scroll(无限滚动)插件** jQuery Infinite Scroll,也称为`infinitescroll.js`,是一款广泛使用的JavaScript插件,它实现了网页内容的自动滚动加载,即当用户滚动到页面底部时,新的内容会自动...

Global site tag (gtag.js) - Google Analytics