繁体   English   中英

Spring Boot Jackson序列化列表对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM