![](/img/trans.png)
[英]In Spring Boot The Jackson With LocalDateTime Serialization Error
[英]Spring Boot Jackson serialization for List Object
我有一个从Spring Boot ReST控制器返回的“人员”对象列表。 除了一个问题外,输出都很好。
此Personnel对象具有一个PersonnelType对象作为其嵌套对象之一。 当序列化列表中的第一个Personnel对象时,PersonnelType的整个子对象都将被序列化,这就是我想要的。
但是,如果列表中的第二个或后续Personnel对象与已经在第一个Personnel对象中序列化的PersonnelType具有相同的PersonnelType(相同的ID),则这些后续的PersonnelType对象将仅使用“ id”而不是整个对象进行序列化。
例如,这是序列化的输出:
[
{
"id": 2,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"workforceId": 9994323221,
"workPhoneNumber": "7034563452",
"workEmailAddress": "xxx@epa.gov",
"currentPosition": "Developer",
"isSponsored": false,
"dateOfSponsorship": null,
"sponsorPersonnelId": null,
"isLEO": true,
"isFERO": false,
"requireComputerAndEmailAccess": true,
"isPriorityCase": false,
"building": {
"id": 1,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"isActive": true,
"buildingName": "Robert C Byrd Courthouse and FOB",
"buildingNumber": "406",
"displayGlobal": false,
"facilityName": "Robert C Byrd Courthouse",
"facilityNumber": "107",
"handler": {},
"hibernateLazyInitializer": {}
},
"personnelType": {
"id": 1,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"description": "Federal Employee",
"isActive": true,
"handler": {},
"hibernateLazyInitializer": {}
}
},
{
"id": 2,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"workforceId": 9994323221,
"workPhoneNumber": "7034563452",
"workEmailAddress": "xxx@epa.gov",
"currentPosition": "Developer",
"isSponsored": false,
"dateOfSponsorship": null,
"sponsorPersonnelId": null,
"isLEO": true,
"isFERO": false,
"requireComputerAndEmailAccess": true,
"isPriorityCase": false,
"building": {
"id": 1,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"isActive": true,
"buildingName": "Robert C Byrd Courthouse and FOB",
"buildingNumber": "406",
"displayGlobal": false,
"facilityName": "Robert C Byrd Courthouse",
"facilityNumber": "107",
"handler": {},
"hibernateLazyInitializer": {}
},
"personnelType": 1
}
]
上面,序列化列表中的第一个Personnel对象具有序列化的PersonnelType的完整对象,而序列化列表中的第二个Personnel对象具有仅序列化的PersonnelType作为id,因为PersonnelType(id = 1)的id与PersonnelType相同在列表中的第一个Personnel对象中。
这是Jackson序列化程序的默认行为吗? 我没有使用@JsonIdentityReference,因此默认情况下它为false。
@JsonIdentityReference标记,指示是否所有参考值都将被序列化为id(true); 或者将遇到的第一个引用序列化为POJO,然后再序列化为id(假)。
如何更改序列化,以便在列表中的每个Personnel对象中返回完整的PersonnelType子对象(即使它已经在List中的先前Personnel对象中进行了一次序列化)?
这是带有注释的我的人员实体:
@Entity
@Table(name = "Personnel", schema = "dbo", catalog = "PSSV2Db")
@EntityListeners(AuditingEntityListener.class)
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id",resolver = EntityIdResolver.class, scope = PersonnelEntity.class)
public class PersonnelEntity extends AuditedEntity<String> {
private Long id;
private Long workforceId;
private String workPhoneNumber;
private String workEmailAddress;
private String UPN;
private String currentPosition;
private Boolean isSponsored;
private LocalDate dateOfSponsorship;
private String sponsorPersonnelId;
private Boolean isLEO;
private Boolean isFERO;
private Boolean requireComputerAndEmailAccess;
private Boolean isPriorityCase;
@Id
@Column(name = "PersonnelId", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Basic
@Column(name = "WorkforceId", nullable = false)
public Long getWorkforceId() {
return workforceId;
}
public void setWorkforceId(Long workforceId) {
this.workforceId = workforceId;
}
@Basic
@Column(name = "WorkPhoneNumber", nullable = true)
public String getWorkPhoneNumber() {
return workPhoneNumber;
}
public void setWorkPhoneNumber(String workPhoneNumber) {
this.workPhoneNumber = workPhoneNumber;
}
@Basic
@Column(name = "WorkEmailAddress", nullable = true)
public String getWorkEmailAddress() {
return workEmailAddress;
}
public void setWorkEmailAddress(String workEmailAddress) {
this.workEmailAddress = workEmailAddress;
}
@Basic
@Column(name = "UPN", nullable = true)
public String getUPN() {
return UPN;
}
public void setUPN(String UPN) {
this.UPN = UPN;
}
@Basic
@Column(name = "CurrentPosition", nullable = true)
public String getCurrentPosition() {
return currentPosition;
}
public void setCurrentPosition(String currentPosition) {
this.currentPosition = currentPosition;
}
@Basic
@Column(name = "IsSponsored", nullable = true)
public Boolean getIsSponsored() {
return isSponsored;
}
public void setIsSponsored(Boolean sponsored) {
this.isSponsored = sponsored;
}
@Basic
@Column(name = "DateOfSponsorship", nullable = true)
public LocalDate getDateOfSponsorship() {
return dateOfSponsorship;
}
public void setDateOfSponsorship(LocalDate dateOfSponsorship) {
this.dateOfSponsorship = dateOfSponsorship;
}
@Basic
@Column(name = "SponsorPersonnelId", nullable = true)
public String getSponsorPersonnelId() {
return sponsorPersonnelId;
}
public void setSponsorPersonnelId(String sponsorPersonnelId) {
this.sponsorPersonnelId = sponsorPersonnelId;
}
@Basic
@Column(name = "IsLEO", nullable = false)
public Boolean getIsLEO() {
return isLEO;
}
public void setIsLEO(Boolean LEO) {
this.isLEO = LEO;
}
@Basic
@Column(name = "IsFERO", nullable = false)
public Boolean getIsFERO() {
return isFERO;
}
public void setIsFERO(Boolean FERO) {
this.isFERO = FERO;
}
@Basic
@Column(name = "RequireComputerAndEmailAddress", nullable = false)
public Boolean getRequireComputerAndEmailAccess() {
return requireComputerAndEmailAccess;
}
public void setRequireComputerAndEmailAccess(Boolean requireComputerAndEmailAccess) {
this.requireComputerAndEmailAccess = requireComputerAndEmailAccess;
}
@Basic
@Column(name = "IsPriorityCase", nullable = false)
public Boolean getIsPriorityCase() {
return isPriorityCase;
}
public void setIsPriorityCase(Boolean isPriorityCase) {
this.isPriorityCase = isPriorityCase;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PersonnelEntity)) return false;
PersonnelEntity that = (PersonnelEntity) o;
return Objects.equals(getId(), that.getId()) &&
Objects.equals(getWorkforceId(), that.getWorkforceId()) &&
Objects.equals(getWorkPhoneNumber(), that.getWorkPhoneNumber()) &&
Objects.equals(getWorkEmailAddress(), that.getWorkEmailAddress()) &&
Objects.equals(getUPN(), that.getUPN()) &&
Objects.equals(getCurrentPosition(), that.getCurrentPosition()) &&
Objects.equals(getIsSponsored(), that.getIsSponsored()) &&
Objects.equals(getDateOfSponsorship(), that.getDateOfSponsorship()) &&
Objects.equals(getSponsorPersonnelId(), that.getSponsorPersonnelId()) &&
Objects.equals(getIsLEO(), that.getIsLEO()) &&
Objects.equals(getIsFERO(), that.getIsFERO()) &&
Objects.equals(getRequireComputerAndEmailAccess(), that.getRequireComputerAndEmailAccess()) &&
Objects.equals(getIsPriorityCase(), that.getIsPriorityCase());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getWorkforceId(), getWorkPhoneNumber(), getWorkEmailAddress(), getUPN(), getCurrentPosition(), getIsSponsored(), getDateOfSponsorship(), getSponsorPersonnelId(), getIsLEO(), getIsFERO(), getRequireComputerAndEmailAccess(), getIsPriorityCase());
}
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "BuildingId")
public BuildingsEntity getBuilding() {
return building;
}
public void setBuilding(BuildingsEntity building) {
this.building = building;
}
private BuildingsEntity building;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "PersonnelTypeId")
public PersonnelTypesEntity getPersonnelType() {
return personnelType;
}
public void setPersonnelType(PersonnelTypesEntity personnelType) {
this.personnelType = personnelType;
}
private PersonnelTypesEntity personnelType;
}
这是带有注释的PersonnelType实体:
@Entity
@Table(name = "PersonnelTypes", schema = "dbo", catalog = "PSSV2Db")
@EntityListeners(AuditingEntityListener.class)
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", resolver = EntityIdResolver.class, scope = PersonnelTypesEntity.class)
public class PersonnelTypesEntity extends AuditedEntity<String> {
private long id;
private String description;
private Boolean isActive;
@Id
@Column(name = "PersonnelTypeId", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Basic
@Column(name = "Description", nullable = true, length = 8000)
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Basic
@Column(name = "IsActive", nullable = false)
public Boolean getIsActive() {
return isActive;
}
public void setIsActive(Boolean isActive) {
this.isActive = isActive;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PersonnelTypesEntity)) return false;
PersonnelTypesEntity that = (PersonnelTypesEntity) o;
return getId() == that.getId() &&
Objects.equals(getDescription(), that.getDescription()) &&
Objects.equals(getIsActive(), that.getIsActive());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getDescription(), getIsActive());
}
}
我使用JSOG库为所有序列化的输出提供@id和@ref,并且API使用者也将需要使用JSOG库进行转换并在客户端上获取完整的对象图。
这似乎是一个常见的问题,但是Jackson本身并未提供解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.