我在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。是否可以使用特定的注释来做到这一点?
答案 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构造:创建一个新类,用于将某些字段暴露给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;
...
}