JAXB MOXy外部绑定文件未被读取

时间:2015-10-13 21:24:01

标签: java xml jaxb

我想使用外部绑定,这样我就可以为相同的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传递什么(即使文件不存在),它也不会抱怨。

1 个答案:

答案 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。即使使用完整路径也不适合我