将Java对象转换为XML

时间:2011-05-11 13:24:46

标签: java xml jaxb oxm

我正在尝试将Java库中的Java对象转换为XML文件。但是,我遇到了这个问题:

A a = new A();

// initializing for a

JAXBContext jc = JAXBContext.newInstance("libraryA.A");

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(a, System.out);

然后我得到了这个例外:

javax.xml.bind.JAXBException: "libraryA.a" doesnt contain ObjectFactory.class or jaxb.index
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:186)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:290)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:244)

如果我改变:JAXBContext jc = JAXBContext.newInstance("libraryA.a");

为:

JAXBContext jc = JAXBContext.newInstance(libraryA.A.class);

然后我有另一个例外:

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions

library.A is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at library.A

library.A does not have a no-arg default constructor.
    this problem is related 

to the following location:
    at library.A

2 个答案:

答案 0 :(得分:14)

背景信息(来自Related Question

根据您对上一个问题的回答所做的评论,域模型已经与JAXB一起使用。让客户端和服务器通过XML进行通信的最简单方法是利用两端已经注释的模型。

  

我刚检查了源代码   我的客户。在这个过程中,我们需要   转换回来的xml文件   从java对象生成到xml   file使用:javax.xml.bind.JAXBContext   &安培; javax.xml.bind.Marshaller。所以我的   问题是可以回读   xml文件到同一个java对象?   然后我们可以使用java对象了   进一步的步骤提前谢谢!


<强>更新

看起来您的问题似乎是由于具有通过具有支持实现类的接口定义的域模型。下面我将演示如何使用JAXB实现(Metro,MOXy,JaxMe等)来处理这个问题。

演示代码

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(CustomerImpl.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Customer customer = (Customer) unmarshaller.unmarshal(xml);

        Address address = customer.getAddress();
        System.out.println(address.getStreet());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }

}

界面模型

以下界面代表我们的域模型。不利用这些接口来引导JAXBContext。

<强> 客户

public interface Customer {

    public Address getAddress();

    public void setAddress(Address address);

}

<强> 地址

public interface Address {

    public String getStreet();

    public void setStreet(String street);

}

实施类

实现类将使用JAXB映射到XML。

<强> CustomerImpl

注意在CustomerImpl类中,我们使用@XmlElement属性上的address注释来指定类型为AddressImpl

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="customer")
public class CustomerImpl implements Customer {

    private Address address;

    @XmlElement(type=AddressImpl.class)
    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

}

<强> AddressImpl

public class AddressImpl implements Address {

    private String street;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

}

<强> input.xml中

<?xml version="1.0" encoding="UTF-8"?>
<customer>
    <address>
        <street>1 Any Street</street>
    </address>
</customer>

答案 1 :(得分:1)

如果您不必使用JAXB,也许可以使用XStream

它对您可以与XML串行化的内容施加的限制非常少,如果您不需要JAXB 专门,则可能是合适的。