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
分享到:
相关推荐
总结起来,Spring Boot 1.5.2结合JPA处理ManyToMany关联时,需要注意双向引用可能导致的无限递归问题,通过`@JsonManagedReference`和`@JsonBackReference`来解决序列化问题,并合理管理事务和级联操作,以确保数据...
@JsonBackReference:处理 JSON 序列化时的循环引用问题,通常配合 @JsonManagedReference 使用,防止在序列化时陷入无限循环。 例如: ```java public class User { @Id private Long id; @ManyToOne @...
2. **使用`@JsonIgnore`**:如果你不希望某个属性被序列化,可以使用`@JsonIgnore`注解。这会阻止Jackson处理该属性,从而避免无限递归。 3. **使用`@JsonIdentityInfo`**:对于复杂的情况,可以使用`@...
首先,Jackson提供了`@JsonManagedReference`和`@JsonBackReference`注解来处理这种关系。`@JsonManagedReference`标记在一个字段上,表示这是引用的一端,而`@JsonBackReference`标记在另一端,表示它是被引用的那...
`@JsonBackReference` 和 `@JsonManagedReference` 是 Jackson 库提供的注解,用于处理 JSON 反序列化时的双向引用问题,防止循环引用。 `@RepositoryRestResource` 与 Spring Data REST 结合,可以将 Repository ...
@JsonBackReference 注解用于解决嵌套外链问题。 7. @RepositoryRestResource @RepositoryRestResource 注解用于将 Spring Data REST repository 暴露为 RESTful 服务。 二、详细解释 1. @SpringBootApplication...
- 避免无限循环:当双向关联时,要注意避免无限递归问题,可以通过`@JsonIgnore`或`@JsonBackReference`和`@JsonManagedReference`注解解决。 关联映射在实际项目中的应用广泛,理解并熟练掌握这些映射方式对于优化...
当一个实体包含对另一个实体的引用,并且另一个实体也引用了这个实体,使用`@JsonBackReference`可以防止在序列化时将被引用的对象包含进来。例如,在`User`实体的`department`字段上添加`@JsonBackReference`注解:...
@JsonManagedReference和@JsonBackReference是一对组合,用于解决这个问题。其中,@JsonManagedReference标记在主引用上,@JsonBackReference标记在从属引用上。 11、@RepositoryRestResource:配合spring-boot-...
可以通过`@JsonIgnore`或`@JsonManagedReference/@JsonBackReference`解决。 5. **性能考虑**:大量数据的`one_to_many`关联可能导致性能下降,因为每次加载关联都可能引发多次数据库查询。优化策略可能包括分页、...
@JsonBackReference 注解用于解决嵌套外链问题,通常用于 JSON 序列化时。 六、@RepositoryRestResource 注解 @RepositoryRestResource 注解用于 public 配合 Spring Boot Starter Data Rest 使用,提供了对数据的...
@JsonBackReference:在处理JSON序列化时,用于解决双向引用导致的循环引用问题。在一对多或多对一的关系中,可以将它放在父实体的一方,避免在序列化时出现循环引用。 @RepositoryRestResource:当配合spring-boot...
@JsonBackReference:在处理JSON序列化时,防止出现循环引用的问题。在一对多或者多对一的关系中,若不加此注解,可能会导致无限递归。 @RepositoryRestResource:配合spring-boot-starter-data-rest使用,可以将一...
在一对多关系中,使用`@JsonManagedReference`标记父对象,`@JsonBackReference`标记子对象,避免无限递归。 7. **@RepositoryRestResource** 当与`spring-boot-starter-data-rest`一起使用时,此注解可以将仓库类...
在处理领域类关系时,Jackson提供了如`@JsonManagedReference`和`@JsonBackReference`来处理一对多和多对一的关系,防止无限循环引用的问题。例如,一个用户可以有多个订单,每个订单又关联到一个用户,不恰当的处理...
6. **@JsonBackReference**: Jackson库中的注解,用于解决JSON序列化时的循环引用问题。当实体A引用实体B,B又引用回A时,可以使用此注解避免无限递归。 7. **@RepositoryRestResource**: 当配合`spring-boot-...
这可以通过注解如`@JsonIgnore`, `@JsonFormat`, `@JsonInclude`和`@JsonBackReference`等来实现。 4. **类型绑定**:Jackson提供了类型绑定机制,使你可以处理未知类型的JSON数据,通过`TypeReference`或`JavaType...
为了避免这种情况,可以在需要的地方添加`@JsonManagedReference`和`@JsonBackReference`注解,指定主从关系,防止循环引用。 通过理解和熟练运用双向多对一关系,我们可以更高效地管理数据,减少数据库交互,提高...
11. **@JsonBackReference** 在处理JSON序列化时,用来解决循环引用的问题,防止无限递归。 12. **@RepositoryRestResource** 当使用`spring-boot-starter-data-rest`时,这个注解可以让Spring Data REST暴露...
11. **JSON 映射**:项目可能会使用 `Jackson` 或其他库进行 JSON 序列化和反序列化,例如 `@JsonManagedReference` 和 `@JsonBackReference` 控制双向引用的序列化行为。 这个"springdatajpademo"项目是一个很好的...