简体   繁体   中英

JAXB Unmarshaller not processing lists in XML correctly

I'm using the JAXB Unmarshaller to convert an XML string into a Java object structure (using Java 7; Java 8 is not an option at this time). I'm having a problem with lists of objects though. (I apologize in advance for all the code included.) This is the input XML string:

<claimImportCompositeDTO>
    <claimId>900</claimId>
    <claimNumber>AT0000000000018</claimNumber>
    <claimDTO>
        <recordId>900</recordId>
        <version>1</version>
        <clmAddress>
            <recordId>900</recordId>
            <version>0</version>
        </clmAddress>
        <claimStatus>
            <expired class="list">
                <claimStatusDTO>
                    <recordId>900</recordId>
                    <version>1</version>
                </claimStatusDTO>
                <claimStatusDTO>
                    <recordId>910</recordId>
                    <version>2</version>
                </claimStatusDTO>
            </expired>
            <statusCompleteWorkItemFlag>false</statusCompleteWorkItemFlag>
        </claimStatus>
    </claimDTO>
    <notes class="list">
        <notepadDTO>
            <recordId>3503</recordId>
            <version>0</version>
            <notepadText class="list">
                <notepadTextDTO>
                    <recordId>3503</recordId>
                    <version>0</version>
                </notepadTextDTO>
                <notepadTextDTO>
                    <recordId>3504</recordId>
                    <version>0</version>
                </notepadTextDTO>
            </notepadText>
        </notepadDTO>
    </notes>
</claimImportCompositeDTO>

This is the definition for the various objects:

import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class ClaimImportCompositeDTO {
    private String _claimId;
    private String _claimNumber;
    private ClaimDTO _claimDTO;
    private List<NotepadDTO> _notes;

    public String getClaimId() {
        return _claimId;
    }

    public String getClaimNumber() {
        return _claimNumber;
    }

    public ClaimDTO getClaimDTO() {
        return _claimDTO;
    }

    public List<NotepadDTO> getNotes() {
        return _notes;
    }

    public void setClaimId(String claimId) {
        this._claimId = claimId;
    }

    public void setClaimNumber(String claimNumber) {
        this._claimNumber = claimNumber;
    }

    public void setClaimDTO(ClaimDTO claimDTO) {
        this._claimDTO = claimDTO;
    }

    public void setNotes(List<NotepadDTO> notes) {
        this._notes = notes;
    }
}


public class ClaimDTO {
    private String _recordId;
    private String _version;
    private ClmAddress _clmAddress;
    private ClaimStatus _claimStatus;

    public String getRecordId() {
        return _recordId;
    }

    public String getVersion() {
        return _version;
    }

    public ClmAddress getClmAddress() {
        return _clmAddress;
    }

    public ClaimStatus getClaimStatus() {
        return _claimStatus;
    }

    public void setRecordId(String recordId) {
        this._recordId = recordId;
    }

    public void setVersion(String version) {
        this._version = version;
    }

    public void setClmAddress(ClmAddress clmAddress) {
        this._clmAddress = clmAddress;
    }

    public void setClaimStatus(ClaimStatus claimStatus) {
        this._claimStatus = claimStatus;
    }
}


public class ClmAddress {
    private String _recordId;
    private String _version;

    public String getRecordId() {
        return _recordId;
    }

    public String getVersion() {
        return _version;
    }

    public void setRecordId(String recordId) {
        this._recordId = recordId;
    }

    public void setVersion(String version) {
        this._version = version;
    }
}


import java.util.List;

public class ClaimStatus {
    private List<ClaimStatusDTO> _expired;
    private boolean _statusCompleteWorkItemFlag;

    public List<ClaimStatusDTO> getExpired() {
        return _expired;
    }

    public boolean isStatusCompleteWorkItemFlag() {
        return _statusCompleteWorkItemFlag;
    }

    public void setExpired(List<ClaimStatusDTO> expired) {
        this._expired = expired;
    }

    public void setStatusCompleteWorkItemFlag(boolean statusCompleteWorkItemFlag) {
        this._statusCompleteWorkItemFlag = statusCompleteWorkItemFlag;
    }
}


public class ClaimStatusDTO {
    private String _recordId;
    private String _version;

    public String getRecordId() {
        return _recordId;
    }

    public String getVersion() {
        return _version;
    }

    public void setRecordId(String recordId) {
        this._recordId = recordId;
    }

    public void setVersion(String version) {
        this._version = version;
    }
}


import java.util.List;

public class NotepadDTO {
    private String _recordId;
    private String _version;
    private List<NotepadTextDTO> _notepadText;

    public List<NotepadTextDTO> getNotepadText() {
        return _notepadText;
    }

    public String getRecordId() {
        return _recordId;
    }

    public String getVersion() {
        return _version;
    }

    public void setNotepadText(List<NotepadTextDTO> notepadText) {
        this._notepadText = notepadText;
    }

    public void setRecordId(String recordId) {
        this._recordId = recordId;
    }

    public void setVersion(String version) {
        this._version = version;
    }
}


public class NotepadTextDTO {
    private String _recordId;
    private String _version;

    public String getRecordId() {
        return _recordId;
    }

    public String getVersion() {
        return _version;
    }

    public void setRecordId(String recordId) {
        this._recordId = recordId;
    }

    public void setVersion(String version) {
        this._version = version;
    }
}

This is the output:

<claimImportCompositeDTO>
    <claimId>900</claimId>
    <claimNumber>AT0000000000018</claimNumber>
    <claimDTO>
        <recordId>900</recordId>
        <version>1</version>
        <clmAddress>
            <recordId>900</recordId>
            <version>0</version>
        </clmAddress>
        <claimStatus>
            <expired class="list">
                <claimStatusDTO>
                    <recordId>null</recordId>
                    <version>null</version>
                </claimStatusDTO>
            </expired>
            <statusCompleteWorkItemFlag>false</statusCompleteWorkItemFlag>
        </claimStatus>
    </claimDTO>
    <notes class="list">
        <notepadDTO>
            <recordId>null</recordId>
            <version>null</version>
            <notepadText class="list"/>
        </notepadDTO>
    </notes>
</claimImportCompositeDTO>

When I run the unmarshaller, the non-list data is read correctly, but anything in a list is skipped. Well, one object is created (regardless of how many are in the list) and all of the fields are null (ie, the claimsStatus -> expired list or the notes list).

I'm hoping I'm missing something fairly basic, but I've been unable to find what that may be. Any ideas?

The problem is that the xml provided does not correspond to the structure of the your POJOs. An easy way to fix it, following your existing setup and coding style is to add @XmlElementWrapper on the fields that are lists of items and change their names. You need to change the 3 following classes to how they look below and it will work:

@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class ClaimImportCompositeDTO {
    private String _claimId;
    private String _claimNumber;
    private ClaimDTO _claimDTO;
    private List<NotepadDTO> _notepadDTO;

    public String getClaimId() {
        return _claimId;
    }

    public String getClaimNumber() {
        return _claimNumber;
    }

    public ClaimDTO getClaimDTO() {
        return _claimDTO;
    }

    @XmlElementWrapper(name = "notes")
    public List<NotepadDTO> getNotepadDTO() {
        return _notepadDTO;
    }

    public void setClaimId(String claimId) {
        this._claimId = claimId;
    }

    public void setClaimNumber(String claimNumber) {
        this._claimNumber = claimNumber;
    }

    public void setClaimDTO(ClaimDTO claimDTO) {
        this._claimDTO = claimDTO;
    }

    public void setNotepadDTO(List<NotepadDTO> notes) {
        this._notepadDTO = notes;
    }
}

ClaimStatus class would be:

@XmlAccessorType(XmlAccessType.PROPERTY)
public class ClaimStatus {


    private List<ClaimStatusDTO> _claimStatusDTO;
    private boolean _statusCompleteWorkItemFlag;

    @XmlElementWrapper(name = "expired")
    public List<ClaimStatusDTO> getClaimStatusDTO() {
        return _claimStatusDTO;
    }

    public void setClaimStatusDTO(List<ClaimStatusDTO> claimStatusDto) {
        this._claimStatusDTO = claimStatusDto;
    }

    public boolean isStatusCompleteWorkItemFlag() {
        return _statusCompleteWorkItemFlag;
    }


    public void setStatusCompleteWorkItemFlag(boolean statusCompleteWorkItemFlag) {
        this._statusCompleteWorkItemFlag = statusCompleteWorkItemFlag;
    }
}

And NotepadDTO:

@XmlAccessorType(XmlAccessType.PROPERTY)
public class NotepadDTO {
    private String _recordId;
    private String _version;
    private List<NotepadTextDTO> _notepadTextDTO;

    @XmlElementWrapper(name = "notepadText")
    public List<NotepadTextDTO> getNotepadTextDTO() {
        return _notepadTextDTO;
    }

    public String getRecordId() {
        return _recordId;
    }

    public String getVersion() {
        return _version;
    }

    public void setNotepadTextDTO(List<NotepadTextDTO> notepadText) {
        this._notepadTextDTO = notepadText;
    }

    public void setRecordId(String recordId) {
        this._recordId = recordId;
    }

    public void setVersion(String version) {
        this._version = version;
    }
}

You need the @XmlElement annotation on the list. Something like this.

@XmlElement(name = "notepadDTO")
private List<NotepadDTO> _notes;

Here's a tutorial I used: https://howtodoinjava.com/jaxb/jaxb-exmaple-marshalling-and-unmarshalling-list-or-set-of-objects/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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