我有2个DTO双向结构Category
和Product
,其中Product
是one-to-many
关系中的多面。我想通过REST
将它们作为JSON传输到前端层。当已经分配了ID(用于更新操作)时,我没有任何问题,但是当ID为空(创建)时,我面临着众所周知的无限递归。
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="categoryId")
public class CategoryDTO implements Serializable {
private Long categoryId;
private String categoryName;
private List<ProductDTO> products = new LinkedList<>();
public void addProduct(ProductDTO product) {
products.add(product);
product.setCategory(this);
}
// remove synchronization method, setters, getters
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="productId")
public class ProductDTO implements Serializable {
private Long productId;
private String productName;
private CategoryDTO category;
// setters, getters
}
但是,当我使用@JsonManagedReference
和@JsonBackReference
时,一切都很好。我收到漂亮的json:
{
"categoryId":null,
"categoryName":"category_name",
"products": [
{
"productId":null,
"productName":"product1"
}
]
}
public class CategoryDTO implements Serializable {
private Long categoryId;
private String categoryName;
@JsonManagedReference
private List<ProductDTO> products = new LinkedList<>();
public void addProduct(ProductDTO product) {
products.add(product);
product.setCategory(this);
}
// remove synchronization method, setters, getters
}
public class ProductDTO implements Serializable {
private Long productId;
private String productName;
@JsonBackReference
private CategoryDTO category;
// setters, getters
}
在两个示例中,其余方面都在下面:
@RestController
public class CategoryController {
@GetMapping(path = "/categories")
public ResponseEntity<CategoryDTO> fetchCategories() {
CategoryDTO category = new CategoryDTO();
category.setCategoryName("category_name");
ProductDTO product1 = new ProductDTO();
product1.setProductName("product1");
category.addProduct(product1);
return new ResponseEntity<>(category, HttpStatus.OK);
}
}
为什么@JsonManagedReference
和@JsonBackReference
有效,而@JsonIdentityInfo
无效?
感谢阅读。
答案 0 :(得分:0)
@JsonManagedReference
和@JsonBackReference
使用对象实例引用,因此,当您将Product
添加到Category
时,而@JsonIdentityInfo
使用来自值的ID时,它可以工作领域。
答案在WritableObjectId
和BeanSerializerBase#_serializeWithObjectId(Object, JsonGenerator, SerializerProvider, boolean)
类别中。
换句话说,对于非空字段,序列化器记得他序列化了给定的类实例,但是他不能对空字段进行序列化。当您按下端点/categories
时,您会看到。在连接中断之前,会生成无限的JSON。
如果我错了,请有人纠正我。
注意: Imo,您只需删除字段private CategoryDTO category
或将其更改为private Long categoryId
,您将摆脱任何注释:D同样,您也不会遇到任何问题无限递归。