如何防止API中嵌套json对象

问题描述 投票:0回答:1

我有一个 Spring Boot 应用程序,前端和后端使用 apache HttpClient 连接。 实体之间存在许多双向关联。例如:

    @NamedEntityGraphs(
    {
        @NamedEntityGraph(name = "graph.ApplicationUserProcesses",
            attributeNodes ={
                @NamedAttributeNode(value = "processes", subgraph = "processes"),
                @NamedAttributeNode(value = "roles")
            },
            subgraphs = @NamedSubgraph(name = "processes",
                attributeNodes = {
                    @NamedAttributeNode("applicationUsers")
                })
        )
    }
)

public class ApplicationUser implements Serializable {

    @Id
    private UUID id;

    @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
    @JoinTable( name = "app_user_role",
        joinColumns = @JoinColumn(name = "app_user_id"),
        inverseJoinColumns = @JoinColumn(name = "app_user_role_id"))
    private Set<Role> roles = new HashSet<>();

    @JsonIgnore
    @ManyToMany(mappedBy = "applicationUsers", fetch = FetchType.LAZY)
    private Set<Process> processes = new HashSet<>();
}





public class Process  implements Serializable {

    @Id
    private UUID id;
    
    @ManyToMany( fetch = FetchType.LAZY)
    @JoinTable( name = "membership",
        joinColumns = @JoinColumn(name = "process_id"),
        inverseJoinColumns = @JoinColumn(name = "user_id"))
    private Set<ApplicationUser> applicationUsers = new HashSet<>();
}

进程和applicationUser实体具有双向关联,如上所示。问题是,当后端返回applicationUser对象时,json中存在连续的对象嵌套(如下所示),这是不需要的。如何让后端的json API停止嵌套。

    applicationUser:{
    processes:[{
        process1:{
            applicationUser:{
                processes:[{
                    process1:{
                    
                    }
                }]
            }
        }
    }]
}

是否有办法防止 json 中对象的嵌套并保持干净的 API。

json rest spring-rest
1个回答
0
投票

您需要使用 Jackson 的

@JsonManagedReference
@JsonBackReference
注释来避免这种情况。

在您希望允许子级包含在 JSON 中的父类上添加

@JsonManagedReference
注释。

public class ApplicationUser implements Serializable {

    @Id
    private UUID id;

    @JsonManagedReference
    @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
    @JoinTable( name = "app_user_role",
        joinColumns = @JoinColumn(name = "app_user_id"),
        inverseJoinColumns = @JoinColumn(name = "app_user_role_id"))
    private Set<Role> roles = new HashSet<>();

    @JsonManagedReference
    @ManyToMany(mappedBy = "applicationUsers", fetch = FetchType.LAZY)
    private Set<Process> processes = new HashSet<>();

}

在您不想在 JSON 中包含父级的子类上添加

@JsonBackReference

public class Process  implements Serializable {

    @Id
    private UUID id;
    
    @JsonBackReference
    @ManyToMany( fetch = FetchType.LAZY)
    @JoinTable( name = "membership",
        joinColumns = @JoinColumn(name = "process_id"),
        inverseJoinColumns = @JoinColumn(name = "user_id"))
    private Set<ApplicationUser> applicationUsers = new HashSet<>();

}

您不应将实体暴露给 API,而应使用 DTO/VO,它们是保存值的 POJO 类。根据您想要如何公开实体关系,尝试使用不同的 POJO 类。或者尝试避免实体中的双向关系,因为通常不需要,因为您总是从父级获得子级,反之亦然。

© www.soinside.com 2019 - 2024. All rights reserved.