我想使用外部绑定,这样我就可以为相同的java类提供多个xml配置,而无需在代码中使用注释。问题是我的程序似乎没有使用我使用的外部绑定文件,而只是默认解组/编组。
我有以下课程:
Customer.java
@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
private String firstName;
private String lastName;
private Address address;
private List<PhoneNumber> phoneNumbers;
//getters and setters
Address.java
public class Address {
private String street;
//getters and setters
}
PhoneNumber.java
public class PhoneNumber {
private String type;
private String number;
//getters and setters
}
Demo.java
public class Demo {
public static void main(String[] args) throws Exception {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream iStream = classLoader.getResourceAsStream("src/blog/bindingfile/binding.xml");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, iStream);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class}, properties);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StreamSource xml = new StreamSource("src/blog/bindingfile/input.xml");
Customer customer = unmarshaller.unmarshal(xml, Customer.class).getValue();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}
我还尝试了另一种版本的Demo.java
public class Demo {
public static void main(String[] args) throws Exception {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream iStream = classLoader.getResourceAsStream("src/blog/bindingfile/binding.xml");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, iStream);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class} , properties);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Customer customer = (Customer) unmarshaller.unmarshal(new File("src/blog/bindingfile/input.xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}
我的Binding.xml如下:
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="blog.bindingfile">
<xml-schema
namespace="http://www.example.com/customer"
element-form-default="QUALIFIED"/>
<java-types>
<java-type name="Customer">
<xml-root-element/>
<xml-type prop-order="firstName lastName address phoneNumbers"/>
<java-attributes>
<xml-element java-attribute="firstName" name="first-name"/>
<xml-element java-attribute="lastName" name="last-name"/>
<xml-element java-attribute="phoneNumbers" name="phone-number"/>
</java-attributes>
</java-type>
<java-type name="PhoneNumber">
<java-attributes>
<xml-attribute java-attribute="type"/>
<xml-value java-attribute="number"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
input.xml是:
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<first-name>Jane</first-name>
<last-name>Doe</last-name>
<address>
<street>123 A Street</street>
</address>
<phone-number type="work">555-1111</phone-number>
<phone-number type="cell">555-2222</phone-number>
</customer>
无论Demo.java我使用的输出是:
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<address>
<street>123 A Street</street>
</address>
</customer>
有人可以告诉我我做错了什么。我注意到无论我作为binding.xml传递什么(即使文件不存在),它也不会抱怨。
答案 0 :(得分:0)
问题在于这一行:
InputStream iStream = classLoader.getResourceAsStream("src/blog/bindingfile/binding.xml");
iStream为空。因为程序找不到该文件。但是它不会抛出任何例外。
然后将此null InputStream传递到
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, iStream);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class} , properties)
同样没有抛出异常,因此unmarshaller / marshaller使用默认规则进行解组/编组,因此我们得到了问题中显示的xml输出。
通过在src文件夹级别添加新文件夹(资源)然后在那里移动binding.xml文件来修复文件错误。然后路径是resources / binding.xml。即使使用完整路径也不适合我