Java JAXBContext.newInstance变体
我正在试验类JAXBContext中各种形式的newInstance方法(我使用Oracle JDK 1.7附带的默认Sun JAXB实现) 我不清楚什么时候可以将具体类传递给newInstance方法,而不是ObjectFactory类。我应该注意到,我使用JAXB纯粹是为了解析XML文件,即仅在XML->Java方向 下面是一段绝对最少的代码,演示了我的观点: xsd文件 有人能解释一下吗?我之所以在这些JAXBContext::newInstance变体上进行实验,是因为我无意中发现,公认的答案包括“基于单个类而不是对象工厂构建JAXB上下文”选项。我正在使用的示例a.xml和JAXBJava代码如下所示 使用的示例a.xmlJava JAXBContext.newInstance变体,java,xml,jaxb,xsd,Java,Xml,Jaxb,Xsd,我正在试验类JAXBContext中各种形式的newInstance方法(我使用Oracle JDK 1.7附带的默认Sun JAXB实现) 我不清楚什么时候可以将具体类传递给newInstance方法,而不是ObjectFactory类。我应该注意到,我使用JAXB纯粹是为了解析XML文件,即仅在XML->Java方向 下面是一段绝对最少的代码,演示了我的观点: xsd文件 有人能解释一下吗?我之所以在这些JAXBContext::newInstance变体上进行实验,是因为我无意中发现,公认
福
JAXB解析代码
publicstaticvoidmain(字符串args[])抛出jaxbeexception、FileNotFoundException{
jaxbcontextjc=null;
消息(“使用包上下文(按任意键:)”;
jc=JAXBContext.newInstance(“example.a”);
工作(jc);//成功
消息(“使用对象工厂(按任意键):”;
jc=JAXBContext.newInstance(example.a.ObjectFactory.class);
工作(jc);//成功
消息(“使用类枚举(按任意键):”;
试一试{
jc=JAXBContext.newInstance(example.a.RootType.class);
工作(jc);//失败
}catch(javax.xml.bind.unmarshaleException e){
e、 printStackTrace();
}
消息(“也使用类枚举和对象工厂(按任意键):”;
jc=JAXBContext.newInstance(example.a.RootType.class,example.a.ObjectFactory.class);
工作(jc);//成功
}
私有静态无效工作(JAXBContext jc)抛出JAXBEException、FileNotFoundException{
解组器u=jc.createUnmarshaller();
RootType root=((JAXBElement)u.unmarshal(新文件输入流(“a.xml”))).getValue();
System.out.println(root.getValue());
}
从XML模式生成的JAXB模型
当从XML模式生成的模型创建JAXBContext
时,我始终建议对生成的类的包名执行此操作
JAXBContext jc = JAXBContext.newInstance("example.a");
使用接受类加载器
参数的newInstance
方法更好。当您从JavaSE环境迁移到JavaEE环境时,这将避免您的悲伤
JAXBContext jc = JAXBContext.newInstance("example.a", example.a.ObjectFactory.class.getClassLoader());
当您在包名上创建JAXBContext
时,JAXB impl假定您从XML模式生成了模型,并拉入ObjectFactory
类,因为它总是生成带有此名称的@XmlRegistry
注释的类
从Java模型开始
这就是我建议人们使用
newInstance
方法获取类的时候。从JAXB类引导JAXBContext
时,名为ObjectFactory
的类没有什么特别之处。@XmlRegistry
注释的任何类都可以扮演ObjectFactory
的角色,因此不会自动查找它。这就是为什么当您明确引用ObjectFactory
时,您的用例能够工作,而当您没有引用时,用例却失败了。非常感谢!一个多星期以来,我一直在试图解决一个类加载器问题,而这个技巧是唯一能让我一切顺利的方法:)
<?xml version="1.0" encoding="UTF-8"?>
<a:root xmlns:a="http://www.example.org/A"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/A A.xsd">
<a:value>foo</a:value>
</a:root>
public static void main (String args[]) throws JAXBException, FileNotFoundException {
JAXBContext jc = null;
message("using package context (press any key:)");
jc = JAXBContext.newInstance("example.a");
work(jc); // SUCCEEDS
message("using Object factory (press any key):");
jc = JAXBContext.newInstance(example.a.ObjectFactory.class);
work(jc); // SUCCEEDS
message("using class enumeration (press any key):");
try {
jc = JAXBContext.newInstance(example.a.RootType.class);
work(jc); // FAILS
} catch (javax.xml.bind.UnmarshalException e) {
e.printStackTrace();
}
message("using class enumeration and Object factory too (press any key):");
jc = JAXBContext.newInstance(example.a.RootType.class, example.a.ObjectFactory.class);
work(jc); // SUCCEEDS
}
private static void work(JAXBContext jc) throws JAXBException, FileNotFoundException {
Unmarshaller u = jc.createUnmarshaller();
RootType root = ((JAXBElement<RootType>)u.unmarshal( new FileInputStream( "a.xml" ))).getValue();
System.out.println( root.getValue() );
}
JAXBContext jc = JAXBContext.newInstance("example.a");
JAXBContext jc = JAXBContext.newInstance("example.a", example.a.ObjectFactory.class.getClassLoader());