【问题标题】:@JsonIgnore just for some specific endpoints@JsonIgnore 仅针对某些特定端点
【发布时间】:2021-02-26 21:57:47
【问题描述】:

我一直在努力解决我的项目中的这个问题:是否可以仅在端点具有特定值时使用注释@JsonIgnore

例如我想在endpoint.equals("xxxxxxxxx")时使用注解,但在endpoint.equals("yyyyyy").时不使用

具有这些关系注释的类有 3 个:

客户


    @OneToMany(mappedBy = "ownerOfTheProduct")
    @JsonIgnore
    private List<Product> ownProducts = new ArrayList<>();
    

类别

    @JsonIgnore
    @OneToMany(mappedBy = "category")
    private List<Product> products;

产品

    @ManyToOne
    @JoinTable(name = "PRODUCT_CATEGORY", joinColumns = @JoinColumn(name = "product_id"), inverseJoinColumns = @JoinColumn(name = "category_id"))
    private Category category;


    @ManyToOne
    @JoinTable(name = "CLIENT_PRODUCT", joinColumns = @JoinColumn(name = "product_id"), inverseJoinColumns = @JoinColumn(name = "client_id"))
    private Client ownerOfTheProduct;

重点是:

如果我不输入@JsonIgnore,我会收到 StackOverflow 错误,json 进入循环并且不会停止。

       "id": 1,
    "name": "Product name",
    "price": 20.0,
    "category": {
        "id": 1,
        "name": "Cleaning",
        "products": [
            {
                "id": 1,
                "name": "Product name",
                "price": 20.0,
                "category": {
                              ...

当我以不同的方式映射并将@JsonIgnore 放入两个类:ClientProduct 时,它起作用了,循环并没有发生更多。但是,当我必须使用其他端点时,productsownerOfTheProduct 字段需要通过 api 显示,它不起作用,因为 @JsonIgnore 已注释。

循环已解决

{
    "id": 1,
    "name": "Product name",
    "price": 20.0,
    "category": {
        "id": 1,
        "name": "Cleaning"
    },
    "ownOfTheProduct": {
        "id": 1,
        "name": "Edited",
        "cpf": "Edited",
        "email": "test",
        "password": "test"
    }
}

其他端点不工作

{
    "id": 1,
    "name": "Edited",
    "cpf": "Edited",
    "email": "test",
    "password": "test"
}

我希望我使用 @JsonIgnore (ownProducts) 映射的字段完全以这种方式显示在此请求中:

{
    "id": 1,
    "name": "Edited",
    "cpf": "Edited",
    "email": "test",
    "password": "test"
    "ownProducts" [
           {
    "id": 1,
    "name": "Product name",
    "price": 20.0,
    "category": {
        "id": 1,
        "name": "Cleaning"
    },
                ]
}

有没有办法改变这种情况?总而言之,我只想将@JsonIgnore 与特定的特定端点一起使用,而不是我的 API 上的每个端点。

我希望你们得到我的问题,无论如何这里是github上存储库的链接:https://github.com/reness0/spring-restapi-ecommerce

【问题讨论】:

    标签: java json jpa spring-data-jpa annotations


    【解决方案1】:

    你不能只使用@JsonIgnore,但你可以使用com.fasterxml.jackson.core中的@JsonView@JsonIdentityInfo注解

    它是如何工作的:

    1. 您需要使用接口定义类。例如:

      public class SomeView {
      
          public interface  id {}
      
          public interface CoreData extends id {}
      
          public interface FullData extends CoreData {}
      
      }
      
    2. @JsonView(&lt;some interface.class&gt;)标记实体字段

      public class User {
      
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          @JsonView(SomeView.id.class)
          private Long id;
      
          @Column(nullable = false)
          @JsonView(SomeView.CoreData.class)
          private String username;
      
          @Column(nullable = false)
          @JsonView(SomeView.FullData.class)
          private String email;
      }
      
    3. @JsonView(&lt;some interface.class&gt;)注释端点

       @GetMapping()
       @JsonView(SomeView.FullData.class)
       public User getUser() {
           return <get user entity somwhere>
       }
      

    如果@JsonView(SomeView.id.class) 你会得到这个 JSON:

        {
            id: <some id>
        }
    

    万一@JsonView(SomeView.CoreData.class)

        {
            id: <some id>,
            username: <some username>
        }
    

    万一@JsonView(SomeView.FullData.class):

        {
            id: <some id>,
            username: <some username>,
            email: <some email>
        }
    

    @JsonView 也适用于嵌入对象,您可以使用多个视图类注释一个字段 - @JsonView({SomeView.FullData.class, SomeOtherView.OtherData.class})

    关于循环 JSON。用

    注释你的实体类
    @JsonIdentityInfo(
        property = "id",
        generator = ObjectIdGenerators.PropertyGenerator.class
    )
    

    每次 JSON 序列化循环时,对象数据都会被替换为对象 id 或实体字段供您选择。

    或者你也可以只使用 DTO 类

    【讨论】:

      【解决方案2】:

      虽然使用基于注释的方法无法实现这一点(注释使其成为静态),但您可以使用任何数据映射器库来实现相同的目标。根据 API 中的属性创建过滤器。可以使用Orika库:https://www.baeldung.com/orika-mapping

      【讨论】:

        猜你喜欢
        • 2021-02-10
        • 1970-01-01
        • 2020-09-26
        • 2017-07-18
        • 2016-10-06
        • 2019-03-25
        • 2019-03-12
        • 2019-04-08
        • 1970-01-01
        相关资源
        最近更新 更多