REST控制器中具有一对多关系的实体的递归JSON视图 [英] Recursive JSON view of an entity with one-to-many relationship in REST controller

查看:113
本文介绍了REST控制器中具有一对多关系的实体的递归JSON视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用SpringBoot和JPA来构建REST接口。

I'm using SpringBoot and JPA to build a REST interface.

现在,我为从数据库中提取的产品列表返回了一个奇怪的JSON。假设我有:

Now, I have a strange JSON returned for the list of products fetched from the database. Let's say that I have:

@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<Product> products = Collections.emptyList();

    ...
}

JPA存储库产品定义为:

The JPA repository for the Product is defined as:

public interface ProductRepository extends JpaRepository<Product, Long> {
    List<Product> findAll();
}

在我的控制器中我有:

@Autowired
private ProductRepository productRepo;

@RequestMapping("/all-products", method = RequestMethod.GET)
public Map<String,Object> home() {
    Map<String,Object> model = new HashMap<String,Object>();
    model.put("products", productRepo.findAll());
    return model;
}

令我疯狂的是,如果我尝试将此服务称为如下:

What is driving my crazy, is that if I try to call this service as follows:

$ 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 serializer就是这样:

You're not doing anything wrong (at least at the code level it's rather conceptual) - json serializer just goes like this:


  1. 产品 - 序列化它,但等待 - 有一个类别字段,因此序列化程序必须序列化类别字段

  2. 类别 - 序列化它但是哇它 - 有一个产品领域,因此序列化器必须序列化列表中的每个产品

  3. 产品 - 因为您的产品系列包含产品&产品包含类别,它进入无限循环,直到超时。

您必须使用视图或跳过它。

You must use a view or just skip it.


  1. 使用 @JsonView

使用以POJO
查看返回 new ProductView ,其中包含产品的所有字段和新的CategoryView (你可以在这一点结束)有(产品)新ProductViewWithoutReferences 的集合,依此类推

Use a view as a POJO Return new ProductView that has all fields of product and a reference (category) to new CategoryView (you can end at this point) that has collection of (products) new ProductViewWithoutReferences, and so on

对产品系列使用 @JsonIgnore

并且作为旁注 - 如果它是 @RestController 而你正在调用所有产品那么返回其他东西而不是列表有点不寻常。在地图中包装响应是多余的。许多其他客户端在调用 list()方法时需要一个列表。

And as a side note - if it's a @RestController and you're invoking "all-products" then it's a bit unusual to return something else than a list. Wrapping the response in a map is redundant. Many rest clients expect a list when they invoke list() method.

这篇关于REST控制器中具有一对多关系的实体的递归JSON视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆