仅返回json中的ID而不是完整实体对象

时间:2017-12-22 23:00:10

标签: spring

我在Spring Boot中从RESTful应用程序创建响应时遇到问题。我有一个包含2个子实体属性的实体。

@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "attendances")
public class Attendance {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "version")
    private long version;

    @CreatedDate
    @Column(name = "date_created")
    private Date dateCreated;

    @LastModifiedDate
    @Column(name = "last_created")
    private Date lastUpdated;

    @ManyToOne
    @JoinColumn(name = "member_id")
    @NotNull
    private Member member;

    @ManyToOne
    @JoinColumn(name = "meeting_id")
    @NotNull
    private Meeting meeting;

getters, setters..
}

当我获得有关此数据的JSON时,我总是使用完整的成员和会议实体获得完整对象。在这种情况下,我只需要会员ID和会议ID。是否可以使用特定的注释来做到这一点?

3 个答案:

答案 0 :(得分:4)

注释解决方案

可以使用JSON视图的注释@JsonView

public class View {
    interface Summary {}
}

@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "attendances")
public class Attendance {

    ...

    @JsonView(View.Summary.class)
    @ManyToOne
    @JoinColumn(name = "member_id")
    @NotNull
    private Member member;

    @JsonView(View.Summary.class)
    @ManyToOne
    @JoinColumn(name = "meeting_id")
    @NotNull
    private Meeting meeting;

    ...
}

@RestController
public class ExampleController {

    @JsonView(View.Summary.class)
    @RequestMapping(...)
    public Attendance annotationShowCase() {
        Attendance attendance = // retrieve attendance
        return attendance;
    }
}

由于annotationShowCase()使用@JsonView(View.Summary.class)进行了注释,因此返回的Attendance只会显示同时使用@JsonView(View.Summary.class)注释的字段。

DTO解决方案

此解决方案使用DTO构造:创建一个新类,用于将某些字段暴露给JSON

public class AttendanceSummary {

    private long memberId;
    private long meetingId;

    public AttendanceSummary(Attendance attendance) {
        this.memberId = attendance.getMemberId();
        this.meetingId = attendance.getMeetingId();
    }

    // getters and setters
}

@RestController
public class ExampleController {

    @RequestMapping(...)
    public AttendanceSummary dtoShowCase() {
        Attendance attendance = // retrieve attendance
        return new AttendanceSummary(attendance);
    }
}

答案 1 :(得分:0)

因为杰克逊默认使用getters创建json。您可以使用技巧。您需要覆盖默认的获取方法以返回对象的ID。就像前面提到的Leroy一样,您需要创建视图。您应该使用@Transient批注创建两个字段,这意味着休眠状态不会将这些字段映射到实体,然后通过@JsonView批注在这些字段上设置新视图。从现在开始,您不需要任何其他的DTO包装器。

 public class View {
    interface Summary {}
}

@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "attendances")
public class Attendance {

    ...
    @ManyToOne
    @JoinColumn(name = "member_id")
    @NotNull
    private Member member;

    @ManyToOne
    @JoinColumn(name = "meeting_id")
    @NotNull
    private Meeting meeting;
    
    @JsonView(View.Summary.class)
    @Transient
    private Long memberId;

    @JsonView(View.Summary.class)
    @Transient
    private Long meetingId

    public Long getMemberId() {
       return member.getId();
    }

    public Long getMeetingId() {
       return meeting.getId();
    }
    ...
}

@RestController
public class ExampleController {

    @JsonView(View.Summary.class)
    @RequestMapping(...)
    public Attendance annotationShowCase() {
        Attendance attendance = // retrieve attendance
        return attendance;
    }
}

答案 2 :(得分:0)

如果您特别希望只返回“id”或实体字段之一,则可以使用 @JsonIdentityInfo@JsonIdentityReference 批注来获取工作完成。

示例:

    @Entity
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    class Member {
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       private Long id;
       ....
    }

    @Entity
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    class Meeting {
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       private Long id;
       ....
    }

    @Entity
    @EntityListeners(AuditingEntityListener.class)
    @Table(name = "attendances")
    public class Attendance {

        ...

        @ManyToOne
        @JoinColumn(name = "member_id")
        @NotNull
        @JsonIdentityReference(alwaysAsId = true)
        private Member member;

        @ManyToOne
        @JoinColumn(name = "meeting_id")
        @NotNull
        @JsonIdentityReference(alwaysAsId = true)
        private Meeting meeting;

        ...
    }