JAXB - 反编组不起作用

问题描述:

我有小问题,解组。让我们来看看这个方法:JAXB - 反编组不起作用

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。哪里不对?有人能帮助我吗?

+1

而什么意思'不起作用'? – Jens

+0

始终unmarhall导致异常,并且不会从XML加载到ObservableList。 – wienio

+0

然后添加stacktrace到你的问题 – Jens

有2个问题:

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

请注意,这是一个好主意,使房地产领域最终使编译器抱怨,如果这样的字段未初始化/重新分配:

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