`
vivus
  • 浏览: 117247 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

@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
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

    Jackson通过`@JsonManagedReference`和`@JsonBackReference`注解来解决双向引用的问题。`@JsonManagedReference`标记在父引用上,`@JsonBackReference`标记在子引用上。这两个注解一起工作,确保在序列化时只处理一...

    Hibernate 的关联映射

    - 避免无限循环:当双向关联时,要注意避免无限递归问题,可以通过`@JsonIgnore`或`@JsonBackReference`和`@JsonManagedReference`注解解决。 关联映射在实际项目中的应用广泛,理解并熟练掌握这些映射方式对于优化...

    hibernate one_to_many

    可以通过`@JsonIgnore`或`@JsonManagedReference/@JsonBackReference`解决。 5. **性能考虑**:大量数据的`one_to_many`关联可能导致性能下降,因为每次加载关联都可能引发多次数据库查询。优化策略可能包括分页、...

    Jackson-Annotations-Domain-Relationships:Java域类的Jackson注释演示

    在处理领域类关系时,Jackson提供了如`@JsonManagedReference`和`@JsonBackReference`来处理一对多和多对一的关系,防止无限循环引用的问题。例如,一个用户可以有多个订单,每个订单又关联到一个用户,不恰当的处理...

    spring-hibernate-jackson-error

    可以尝试使用`@JsonManagedReference`和`@JsonBackReference`来解决循环引用问题。 3. **实体类的可见性**:如果id字段的访问级别不是public,Jackson可能无法访问它。确保id字段是可序列化的。 4. **自定义序列化...

Global site tag (gtag.js) - Google Analytics