我正在使用SpringBoot和JPA构建一个REST接口。
现在,我为从数据库中获取的产品列表返回了一个奇怪的JSON。假设我有:
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name ="categoryId", nullable = false, updatable = false)
private Category category;
...
}
@Entity
public class Category implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(mappedBy ="category", cascade = CascadeType.DETACH)
@OrderBy("name ASC")
private List products = Collections.emptyList();
...
}
Product的JPA存储库定义为:
public interface ProductRepository extends JpaRepository {
List findAll();
}
号
在我的控制器中,我有:
@Autowired
private ProductRepository productRepo;
@RequestMapping("/all-products", method = RequestMethod.GET)
public Map home() {
Map model = new HashMap();
model.put("products", productRepo.findAll());
return model;
}
让我发疯的是,如果我尝试以下方式调用此服务:
$ curl localhost:8080/all-products
。
由于表Product和category之间的关系,我得到了一个递归输出,例如:
{"products":[{"id":1,"name":"Product1","category":
{"id":1,"name":"Cat1","products":[{"id":6,"name":"Product6","category":
{"id":1,"name":"Cat1","products":[{"id":6,"name":"Product6","category":
{"id":1,...
我做错什么了?
您没有做错任何事情(至少在代码级别上,这是概念性的)——JSON序列化程序如下所示:
产品-序列化它,但等待-有一个类别字段,因此序列化程序必须序列化类别字段
category-序列化它,但wait-有一个products字段,因此序列化程序必须序列化列表中的每个产品
产品-因为您的集合包含产品&产品包含类别,所以在超时之前,它将无休止地循环。
你必须使用一个视图或者跳过它。
使用@JsonView。
将视图用作POJO返回包含产品所有字段的new ProductView和包含(产品)new ProductViewWithoutReferences集合的new CategoryView的引用(类别),依此类推。
在产品集合上使用@JsonIgnore。
作为旁注,如果它是一个@RestController,而你调用的是"所有产品",那么返回列表以外的东西有点不寻常。将响应包装在映射中是多余的。许多REST客户机在调用list()方法时都希望得到一个列表。
@Jeanvaljean您只需对类的字段进行注释,当序列化发生时应跳过该字段。@JsonIgnore private Listproducts...。
添加@jsonignore对我有效
@OneToMany(mappedBy ="policy")
@JsonIgnore
private List payments;
@你是最棒的
我知道有点晚了,但在这里添加它以防任何人面临同样的问题。下面是另一个相关的答案,我可以找到讨论类似主题的答案。
https://stackoverflow.com/a/3359884/6785908
在这里引用
Jackson 1.6 has annotation-based support for handling such
parent/child linkage, see
http://wiki.fasterxml.com/JacksonFeatureBiDirReferences.
You can of course already exclude serialization of parent link already
using most JSON processing packages (jackson, gson and flex-json at
least support it), but the real trick is in how to deserialize it back
(re-create parent link), not just handle serialization side. Although
sounds like for now just exclusion might work for you.
EDIT (April 2012): Jackson 2.0 now supports true identity
references, so you can solve it this way also.
号