当 class 是 XmlAccessType.NONE 时,如何 JAXB-marshall JavaFX 属性 classes?
How to JAXB-marshall JavaFX Property classes when class is XmlAccessType.NONE?
我想要一个 Java class 包含 JavaFX 属性 对象(Double属性、String属性、Integer属性) 使用 JAXB 的 marshall() 方法调用写入 XML 文件。但是,这个 class 包含很多我不想写入 XML 的数据。这个class预计开发者会经常修改,所以我更喜欢把class标记为“@XmlAccessorType(XmlAccessType.NONE)”,然后加上@XmlElement 标记到我想要写入 XML 的任何内容(因此开发人员不会将一些新成员变量添加到此 class 然后不小心更改 XML 文件的格式)。
我看到了诸如 http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html 之类的示例,但是其中 none 的主要 class 具有“@XmlAccessorType(XmlAccessType.NONE) ”。当我将此标记添加到我的 class 时,我得到运行时异常(因为 JAXB 无法创建新对象)或输出中的空 XML 标记(因为 JAXB 创建了某种默认对象但是没有将所需的值放入其中)。我对几十个@Xml* 标签组合进行了实验,但我找不到一个有效的组合。
请注意,我无法对任何 DoubleProperty/SimpleDoubleProperty class 进行注释,因为它们是标准 Java API.
的一部分
这是一个代码示例,展示了将 bankAccountBalance 属性 放入 XML 文件中的麻烦。 (您可以忽略其他数据 - 我以 Blaise Doughan 的代码作为本示例的起点)。
package Demo2;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
public class Demo2 {
public static void main(String[] args) throws Exception {
Customer customer = new Customer();
Address address = new Address();
address.setStreet("1 A Street");
customer.setContactInfo(address);
customer.setBankAccountBalance(123.45);
JAXBContext jc = JAXBContext.newInstance(Customer.class, Address.class, PhoneNumber.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}
}
abstract class ContactInfo {
}
class Address extends ContactInfo {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
class PhoneNumber extends ContactInfo {
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
class Customer {
@XmlElement
private ContactInfo contactInfo;
// This tag runs OK but always outputs an empty XML tag ("<bankAccountBalance/>") regardless of the real value.
// @XmlElement
// This tag causes the following error:
// Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
// Invalid @XmlElementRef : Type "class javafx.beans.property.DoubleProperty" or any of its subclasses are not known to this context.
// @XmlElementRef
// This tag causes the following error:
// Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
// Invalid @XmlElementRef : Type "class javafx.beans.property.SimpleDoubleProperty" or any of its subclasses are not known to this context.
// @XmlElementRef(type=SimpleDoubleProperty.class)
private DoubleProperty bankAccountBalance;
public Customer() {
bankAccountBalance = new SimpleDoubleProperty(0);
}
public ContactInfo getContactInfo() {
return contactInfo;
}
public void setContactInfo(ContactInfo contactInfo) {
this.contactInfo = contactInfo;
}
public double getBankAccountBalance() {
return bankAccountBalance.get();
}
public void setBankAccountBalance(double bankAccountBalance) {
this.bankAccountBalance.set(bankAccountBalance);
}
}
只需注释 getter 而不是 DoubleProperty 字段,这样可以很好地绕过 javafx class。不要忘记设置值,以便您看到结果。
@XmlElement
public double getBankAccountBalance() {
return bankAccountBalance.get();
}
我想要一个 Java class 包含 JavaFX 属性 对象(Double属性、String属性、Integer属性) 使用 JAXB 的 marshall() 方法调用写入 XML 文件。但是,这个 class 包含很多我不想写入 XML 的数据。这个class预计开发者会经常修改,所以我更喜欢把class标记为“@XmlAccessorType(XmlAccessType.NONE)”,然后加上@XmlElement 标记到我想要写入 XML 的任何内容(因此开发人员不会将一些新成员变量添加到此 class 然后不小心更改 XML 文件的格式)。
我看到了诸如 http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html 之类的示例,但是其中 none 的主要 class 具有“@XmlAccessorType(XmlAccessType.NONE) ”。当我将此标记添加到我的 class 时,我得到运行时异常(因为 JAXB 无法创建新对象)或输出中的空 XML 标记(因为 JAXB 创建了某种默认对象但是没有将所需的值放入其中)。我对几十个@Xml* 标签组合进行了实验,但我找不到一个有效的组合。
请注意,我无法对任何 DoubleProperty/SimpleDoubleProperty class 进行注释,因为它们是标准 Java API.
的一部分这是一个代码示例,展示了将 bankAccountBalance 属性 放入 XML 文件中的麻烦。 (您可以忽略其他数据 - 我以 Blaise Doughan 的代码作为本示例的起点)。
package Demo2;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
public class Demo2 {
public static void main(String[] args) throws Exception {
Customer customer = new Customer();
Address address = new Address();
address.setStreet("1 A Street");
customer.setContactInfo(address);
customer.setBankAccountBalance(123.45);
JAXBContext jc = JAXBContext.newInstance(Customer.class, Address.class, PhoneNumber.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}
}
abstract class ContactInfo {
}
class Address extends ContactInfo {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
class PhoneNumber extends ContactInfo {
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
class Customer {
@XmlElement
private ContactInfo contactInfo;
// This tag runs OK but always outputs an empty XML tag ("<bankAccountBalance/>") regardless of the real value.
// @XmlElement
// This tag causes the following error:
// Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
// Invalid @XmlElementRef : Type "class javafx.beans.property.DoubleProperty" or any of its subclasses are not known to this context.
// @XmlElementRef
// This tag causes the following error:
// Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
// Invalid @XmlElementRef : Type "class javafx.beans.property.SimpleDoubleProperty" or any of its subclasses are not known to this context.
// @XmlElementRef(type=SimpleDoubleProperty.class)
private DoubleProperty bankAccountBalance;
public Customer() {
bankAccountBalance = new SimpleDoubleProperty(0);
}
public ContactInfo getContactInfo() {
return contactInfo;
}
public void setContactInfo(ContactInfo contactInfo) {
this.contactInfo = contactInfo;
}
public double getBankAccountBalance() {
return bankAccountBalance.get();
}
public void setBankAccountBalance(double bankAccountBalance) {
this.bankAccountBalance.set(bankAccountBalance);
}
}
只需注释 getter 而不是 DoubleProperty 字段,这样可以很好地绕过 javafx class。不要忘记设置值,以便您看到结果。
@XmlElement public double getBankAccountBalance() { return bankAccountBalance.get(); }