我试图将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);
Run Code Online (Sandbox Code Playgroud)
然后我得到了这个例外:
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)
Run Code Online (Sandbox Code Playgroud)
如果我改变: JAXBContext jc = JAXBContext.newInstance("libraryA.a");
至:
JAXBContext jc = JAXBContext.newInstance(libraryA.A.class);
Run Code Online (Sandbox Code Playgroud)
然后我有另一个例外:
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
Run Code Online (Sandbox Code Playgroud)
bdo*_*han 14
背景资料(来自相关问题)
根据您对上一个问题的回答所做的评论,域模型已经与JAXB一起使用.让客户端和服务器通过XML进行通信的最简单方法是利用两端已注释的模型.
我刚检查了客户端的源代码.在此过程中,我们需要使用以下命令将从java对象生成的xml文件转换回xml文件:javax.xml.bind.JAXBContext和javax.xml.bind.Marshaller.所以我的问题是可以将xml文件读回到相同的java对象吗?然后我们可以使用java对象进一步完成.提前致谢!
UPDATE
您的问题似乎是由于具有通过具有支持实现类的接口定义的域模型.下面我将演示如何使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
接口模型
以下接口表示我们的域模型.不利用这些接口来引导JAXBContext.
顾客
public interface Customer {
public Address getAddress();
public void setAddress(Address address);
}
Run Code Online (Sandbox Code Playgroud)
地址
public interface Address {
public String getStreet();
public void setStreet(String street);
}
Run Code Online (Sandbox Code Playgroud)
实现类
实现类是使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
AddressImpl
public class AddressImpl implements Address {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
Run Code Online (Sandbox Code Playgroud)
input.xml中
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<address>
<street>1 Any Street</street>
</address>
</customer>
Run Code Online (Sandbox Code Playgroud)