【问题标题】:JAXB unmarshalling doesn't work when field is declared as List but doesn't work when same field is declared as ArrayListJAXB 解组在字段声明为 List 时不起作用,但在同一字段声明为 ArrayList 时不起作用
【发布时间】:2014-08-24 05:09:09
【问题描述】:

我最近开始编写包含一些 JAXB 可序列化/可反序列化类的代码。其中一个类中有几个列表,我想向其中添加一个新列表。这些列表最初被声明为 ArrayList。同样,get 方法也返回 ArrayList。我将它们全部更改为 List 并添加了新列表以及 List。但在那之后,我无法将此对象的 xml 解组为 JAVA 对象。当我将字段更改回 ArrayList 而没有任何其他更改时,解组工作正常。我还尝试将 DefaultValidationEventHandler 附加到 Unmarshaller,但它在解组时不会吐出任何错误。下面是类和变量名更改后的类的样子

@XmlRootElement(name = "commandSet")
public class CommandSet {

    private final ArrayList<Command> xCommands;

    private final ArrayList<Command> yCommands;

    @Override
    @XmlElementWrapper(name = "xCommands")
    @XmlElement(name = "xCommand", type = Command.class)
    public ArrayList<Command> getXCommands() {
        return this.xCommands;
    }

    @Override
    @XmlElementWrapper(name = "yCommands")
    @XmlElement(name = "yCommand", type = Command.class)
    public ArrayList<Command> getYCommands() {
        return this.yCommands;
    }
}

当 xCommands 和 yCommands 被声明为 List 并且 getter 也返回 List 时,unmarhsalling 不起作用。

在我为解组列表找到的所有示例中,人们使用 List 而不是 ArrayList。任何想法为什么它不适用于 List?

【问题讨论】:

    标签: jaxb unmarshalling


    【解决方案1】:

    关于你的代码我注意到的事情

    我注意到关于您的代码的一些奇怪的事情可能会或可能不会影响您的问题。至少我怀疑您遇到问题的模型与您在问题中发布的模型不同。

    • 您已将字段标记为 final,但从不初始化它们。
    • 您使用 @Override 注释了两个 get 方法,但由于 CommandSet 不继承自任何东西(Object 除外),因此您没有覆盖任何东西。

    完整的工作示例

    Java 模型

    命令集

    在这个版本的CommandSet 类中,我创建了一个属性类型ArrayList 和另一个类型List,以证明它们都可以工作。我还删除了您上面提到的代码的怪异之处。

    import java.util.*;
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement
     public class CommandSet {
    
        private final ArrayList<Command> xCommands;
        private final List<Command> yCommands;
    
        public CommandSet() {
            xCommands = new ArrayList<Command>();
            yCommands = new ArrayList<Command>();
        }
    
        @XmlElementWrapper(name = "xCommands")
        @XmlElement(name = "xCommand")
        public ArrayList<Command> getXCommands() {
            return this.xCommands;
        }
    
        @XmlElementWrapper(name = "yCommands")
        @XmlElement(name = "yCommand")
        public List<Command> getYCommands() {
            return this.yCommands;
        }
    
    }
    

    命令

    public class Command {
    }
    

    演示代码

    演示

    import java.io.File;
    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(CommandSet.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("input.xml");
            CommandSet commandSet = (CommandSet) unmarshaller.unmarshal(xml);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(commandSet, System.out);
        }
    
    }
    

    input.xml/Output

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <commandSet>
        <xCommands>
            <xCommand/>
            <xCommand/>
        </xCommands>
        <yCommands>
            <yCommand/>
            <yCommand/>
        </yCommands>
    </commandSet>
    

    【讨论】:

    • 感谢您的回复。要回答您在代码中注意到的奇怪行为: 1. 字段在实际代码中的构造函数中初始化,就像您在示例中所做的那样。 2. 该类正在实现一个接口,而 @Override 正是因为如此。我认为项目的设置方式有问题,因为当字段被声明为 List 时它不起作用。我将尝试创建一个单独的项目来测试它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    相关资源
    最近更新 更多