@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