【问题标题】:JAXB Unmarshaller not processing lists in XML correctlyJAXB Unmarshaller 未正确处理 XML 中的列表
【发布时间】:2018-03-15 14:53:53
【问题描述】:

我正在使用 JAXB Unmarshaller 将 XML 字符串转换为 Java 对象结构(使用 Java 7;目前还不能选择 Java 8)。不过,我对对象列表有疑问。 (我提前为包含的所有代码道歉。)这是输入的 XML 字符串:

<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>

这是各种对象的定义:

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;
    }
}

这是输出:

<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>

当我运行解组器时,非列表数据被正确读取,但列表中的任何内容都被跳过。好吧,创建了一个对象(无论列表中有多少),并且所有字段都为空(即,claimsStatus -> expired 列表或 notes 列表)。

我希望我错过了一些相当基本的东西,但我一直无法找到可能是什么。有什么想法吗?

【问题讨论】:

    标签: java jaxb unmarshalling


    【解决方案1】:

    问题是提供的 xml 与您的 POJO 的结构不对应。按照您现有的设置和编码风格,一种简单的修复方法是在作为项目列表的字段上添加 @XmlElementWrapper 并更改它们的名称。您需要将以下 3 个类更改为它们在下面的外观,它将起作用:

    @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 类将是:

    @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;
        }
    }
    

    和记事本DTO:

    @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;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您需要列表中的@XmlElement 注解。像这样。

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

      这是我使用的教程: https://howtodoinjava.com/jaxb/jaxb-exmaple-marshalling-and-unmarshalling-list-or-set-of-objects/

      【讨论】:

      • 我尝试将 '@XmlElement' 添加到每个列表中,并将 '@XmlRootElement(name = "whatever")' 添加到每个类中。这似乎没有什么不同。我分别和一起尝试了这两种方法。如果我添加了“@XmlAccessorType (XmlAccessType.FIELD)”(来自您的教程),则根本不会加载任何内容(因为外部父对象中的所有内容都是空的)。
      • 这里解释和展示了它的行为原因:stackoverflow.com/questions/48888250/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-15
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多