【问题标题】:JAXB - unmarshal doesn't workJAXB - 解组不起作用
【发布时间】:2017-03-27 13:11:26
【问题描述】:

我对解组器有一个小问题。我们来看看这个方法:

public void loadProductDataFromFile (File file) {
    try {
        JAXBContext context = JAXBContext.newInstance(ProductListWrapper.class);
        Unmarshaller um = context.createUnmarshaller();
        ProductListWrapper wrapper = (ProductListWrapper) um.unmarshal(file);   // this always cause exception

        products.clear();
        products.addAll(wrapper.getProducts());

        setProductFilePath(file);
    } catch (Exception e) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("Fail!");
        alert.setHeaderText("Can't read data!");
        alert.setContentText("Can't read data from:\n" + file.getPath() );
        alert.showAndWait();
    }
}

这是我的 ProductListWrapper:

@XmlRootElement(name = "products")
public class ProductListWrapper {
    private List<Product> products;

    @XmlElement(name = "products")
    public List<Product> getProducts() {
        return products;
    }

    public void setProducts(List<Product> products) {
        this.products=products;
    }
}

我的 XML 文件:

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<products>
     <products>
           <amount>124</amount>
           <ifConttainsPreservatives>false</ifConttainsPreservatives>
           <name>Apple</name>
           <type>FRUITS</type>
     </products>
</products>

还有我从 ObservableList 中保存的方法(我认为可行):

 public void saveProductsDataToFile(File file) {
        try {
            JAXBContext context = JAXBContext.newInstance(ProductListWrapper.class);
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            ProductListWrapper wrapper = new ProductListWrapper();
            wrapper.setProducts(products);
            m.marshal(wrapper, file);
            setProductFilePath(file);
        } catch (Exception e) {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("Fail!");
            alert.setHeaderText("Can't save data!");
            alert.setContentText("Can't save data to:\n" + file.getPath() );
            alert.showAndWait();
        }

我的 Product.class:

public class Product {
    private StringProperty name;
    private IntegerProperty amount;
    private ProductType type;
    private BooleanProperty ifConttainsPreservatives;

    public void setType(ProductType type) {
        this.type = type;
    }

    public String getName() {
        return name.get();
    }

    public boolean isIfConttainsPreservatives() {
        return ifConttainsPreservatives.get();
    }

    public void setName(String name) {
        this.name.set(name);
    }

    public void setAmount(int amount) {
        this.amount.set(amount);
    }

    public void setIfConttainsPreservatives(boolean ifConttainsPreservatives) {
        this.ifConttainsPreservatives.set(ifConttainsPreservatives);
    }

    public ProductType getType() {

        return type;
    }

    public BooleanProperty ifConttainsPreservativesProperty() {
        return ifConttainsPreservatives;
    }

    public StringProperty nameProperty() {
        return name;
    }

    public int getAmount() {
        return amount.get();
    }

    public IntegerProperty amountProperty() {
        return amount;
    }

    public Product(int amount, boolean ifContainsPreservatives, String name, ProductType type) {
        this.name = new SimpleStringProperty(name);
        this.amount = new SimpleIntegerProperty(amount);
        this.ifConttainsPreservatives = new SimpleBooleanProperty(ifContainsPreservatives);
        this.type =type;
    }

    public Product() {
    }
}

类型是 IntegerProperty、ProductType (enum)、StringProperty 和 BooleanProperty。怎么了?有人可以帮帮我吗?

【问题讨论】:

  • 那么doesn't work是什么意思?
  • 总是 unmarhall 导致异常并且不会从 XML 加载到 ObservableList。
  • 然后将堆栈跟踪添加到您的问题中
  • 什么例外?并且,请仔细查看您的 XML。出现意外破折号 (-)。它是存在于您的文件中还是错字?
  • 如果你给你的程序提供正确的输入,你也会得到很多NullPointerExceptions,因为你在Product类中的XXXPropertys没有初始化。 unmarshaller 和 marshaller 都应该停留在该类的 setter/gett 中。

标签: java javafx jaxb unmarshalling


【解决方案1】:

有两个问题:

  1. xml 文件无效。 standalone 的值应为 yes 而不是 true
  2. 不要在没有 jaxb 将使用的参数的构造函数中创建 Product 的属性。

你需要做一些改变:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<products>
     <products>
           <amount>124</amount>
           <ifConttainsPreservatives>false</ifConttainsPreservatives>
           <name>Apple</name>
           <type>FRUITS</type>
     </products>
</products>
public class Product {
    ...

    public Product() {
        // invoke constructor that does assign the properties
        this(0, false, null, null);
    }
}

请注意,如果此类字段未初始化/重新分配,最好将属性字段设为 final 以使编译器抱怨:

private final StringProperty name;
private final IntegerProperty amount;
private ProductType type;
private final BooleanProperty ifConttainsPreservatives;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 2023-03-14
    • 2020-11-15
    • 2014-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    相关资源
    最近更新 更多