我正在按照这个经常被引用的博客文章中使用xsi:type的说明进行操作:
http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html
基本上我有这个:
public abstract class ContactInfo {
}
public class Address extends ContactInfo {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
@XmlRootElement
public class Customer {
private ContactInfo contactInfo;
public ContactInfo getContactInfo() {
return contactInfo;
}
public void setContactInfo(ContactInfo contactInfo) {
this.contactInfo = contactInfo;
}
}
这个测试:
@Test
public void contactTestCase() throws JAXBException, ParserConfigurationException, IOException, SAXException {
Customer customer = new Customer();
Address address = new Address();
address.setStreet("1 A Street");
customer.setContactInfo(address);
JAXBContext jc = JAXBContext.newInstance(Customer.class, Address.class, PhoneNumber.class);
StringWriter writer = new StringWriter();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, writer);
String s = writer.toString();
System.out.append(s);
StringInputStream sis = new StringInputStream(s);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = documentBuilderFactory.newDocumentBuilder();
Document doc = db.parse(sis);
Unmarshaller um = jc.createUnmarshaller();
JAXBElement result = um.unmarshal(doc, Customer.class);
Customer f = (Customer) result.getValue();
writer = new StringWriter();
marshaller.marshal(customer, writer);
s = writer.toString();
System.out.append(s);
}
我得到了这个结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
<contactInfo xsi:type="address" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<street>1 A Street</street>
</contactInfo>
</customer>
javax.xml.bind.UnmarshalException: Unable to create an instance of blog.inheritance.ContactInfo
我已经尝试了JAXB的默认实现,jaxb-impl-2.1.2并基于此bug,我尝试了jaxb-impl-2.2.6-b38.jar。它都不起作用。
这不应该起作用,还是我错过了一些设置?
答案 0 :(得分:5)
在您的测试用例中,您需要指定DocumentBuilderFactory
可识别名称空间。如果没有此设置,JAXB实现的DOM输入将不包含正确形成的xsi:type
属性。
documentBuilderFactory.setNamespaceAware(true);