zoukankan      html  css  js  c++  java
  • springmvc @ResponseBody 返回json数据错误

     

    原因:父子关系,导致jackson 死循环: 解决方案如下:见红色处

    @JsonBackReference @JsonManagedReference @JsonIgnore

     
    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 
    Java代码  收藏代码
    1. import java.util.ArrayList;  
    2. import java.util.List;  
    3.   
    4. import org.codehaus.jackson.annotate.JsonBackReference;  
    5. import org.codehaus.jackson.annotate.JsonManagedReference;  
    6.   
    7. public class TreeNode {  
    8.     String name;  
    9.     @JsonBackReference  
    10. //  @JsonIgnore  
    11.     TreeNode parent;  
    12.     @JsonManagedReference  
    13.     List<TreeNode> children;  
    14.   
    15.     public TreeNode() {  
    16.     }  
    17.   
    18.     public TreeNode(String name) {  
    19.         this.name = name;  
    20.     }  
    21.   
    22.     public String getName() {  
    23.         return name;  
    24.     }  
    25.   
    26.     public void setName(String name) {  
    27.         this.name = name;  
    28.     }  
    29.   
    30.     public TreeNode getParent() {  
    31.         return parent;  
    32.     }  
    33.   
    34.     public void setParent(TreeNode parent) {  
    35.         this.parent = parent;  
    36.     }  
    37.   
    38.     public List<TreeNode> getChildren() {  
    39.         return children;  
    40.     }  
    41.   
    42.     public void setChildren(List<TreeNode> children) {  
    43.         this.children = children;  
    44.     }  
    45.   
    46.     public void addChild(TreeNode child) {  
    47.         if (children == null)  
    48.             children = new ArrayList<TreeNode>();  
    49.         children.add(child);  
    50.     }  
    51. }  

    JsonTest.java 
    Java代码  收藏代码
    1. import java.io.IOException;  
    2.   
    3. import org.codehaus.jackson.JsonGenerationException;  
    4. import org.codehaus.jackson.map.JsonMappingException;  
    5. import org.codehaus.jackson.map.ObjectMapper;  
    6. import org.junit.AfterClass;  
    7. import org.junit.BeforeClass;  
    8. import org.junit.Test;  
    9.   
    10. public class JsonTest {  
    11.     static TreeNode node;  
    12.   
    13.     @BeforeClass  
    14.     public static void setUp() {  
    15.         TreeNode node1 = new TreeNode("node1");  
    16.         TreeNode node2 = new TreeNode("node2");  
    17.         TreeNode node3 = new TreeNode("node3");  
    18.         TreeNode node4 = new TreeNode("node4");  
    19.         TreeNode node5 = new TreeNode("node5");  
    20.         TreeNode node6 = new TreeNode("node6");  
    21.   
    22.         node1.addChild(node2);  
    23.         node2.setParent(node1);  
    24.         node2.addChild(node3);  
    25.         node3.setParent(node2);  
    26.         node2.addChild(node4);  
    27.         node4.setParent(node2);  
    28.         node3.addChild(node5);  
    29.         node5.setParent(node3);  
    30.         node5.addChild(node6);  
    31.         node6.setParent(node5);  
    32.   
    33.         node = node3;  
    34.     }  
    35.   
    36.     @Test  
    37.     public void test() throws JsonGenerationException, JsonMappingException, IOException {  
    38.         ObjectMapper mapper = new ObjectMapper();  
    39.         String json = mapper.writeValueAsString(node);  
    40.         System.out.println(json);  
    41.         TreeNode readValue = mapper.readValue(json, TreeNode.class);  
    42.         System.out.println(readValue.getName());  
    43.     }  
    44.   
    45.     @AfterClass  
    46.     public static void tearDown() {  
    47.         node = null;  
    48.     }  
    49. }  


    参考: 
    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
     
     
  • 相关阅读:
    The required MAP capability is more than the supported max container capability in the cluster. Killing the Job. mapResourceRequest: <memory:2048, vCores:2> maxContainerCapability:<memory:1024, vCores
    centos6.8安装cdh6.0.0
    oracle拼接sql
    数据插入不覆盖更新,设置定时任务
    支持向量机在 R 语言中的实现和使用
    怎么彻底去掉office365
    汽车电子软件规范学习
    ISO/IEC TS 17961 C Secure Coding Rules
    UML图
    Gitflow工作流程
  • 原文地址:https://www.cnblogs.com/eggbucket/p/2781071.html
Copyright © 2011-2022 走看看