JAXBContext.newInstance变体 [英] JAXBContext.newInstance variations

查看:951
本文介绍了JAXBContext.newInstance变体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在类 JAXBContext 中尝试各种形式的 newInstance 方法(我正在使用Oracle JDK 1.7附带的默认Sun JAXB实现)。

I am experimenting with the various forms of newInstance method in class JAXBContext (I am using the default Sun JAXB implementation that ships with Oracle JDK 1.7).

我不清楚何时可以将具体类与 ObjectFactory 类传递给 newInstance 方法。我应该注意,我正在使用JAXB纯粹用于解析XML文件,即仅在XML-> Java方向。

It's not clear to me when it's ok to just pass to the newInstance method the concrete classes versus the ObjectFactory class. I should note that I am using JAXB purely for parsing XML files, i.e. only in the XML->Java direction.

这是绝对最小的代码,它证明了我的观点: / p>

xsd文件



Here's the absolutely minimal code that demonstrates my point:

<?xml version="1.0" encoding="UTF-8"?>
<schema elementFormDefault="qualified"
    xmlns          ="http://www.w3.org/2001/XMLSchema"
    xmlns:a        ="http://www.example.org/A"
    targetNamespace="http://www.example.org/A">
    <element name="root" type="a:RootType"></element>

    <complexType name="RootType">
       <sequence>
           <element name="value" type="string"></element>
       </sequence>
    </complexType>
</schema>

鉴于上述XSD,以下 JAXBInstance.newInstance 调用成功创建可以解析样本 a.xml 文件的上下文:

Given the above XSD, the following JAXBInstance.newInstance invocations succeed in creating a context that can parse a sample a.xml file:


  • jc = JAXBContext.newInstance(示例。 a);

  • jc = JAXBContext.newInstance(example.a.ObjectFactory.class);

  • jc = JAXBContext.newInstance(example.a.RootType.class,example.a.ObjectFactory.class);

但是,单独传递 example.a.RootType.class 会在运行时失败 javax.xml.bind.UnmarshalException

However, passing the example.a.RootType.class alone fails with javax.xml.bind.UnmarshalException at runtime:

jc = JAXBContext.newInstance(example.a.RootType.class); // this fails at runtime.

任何人都可以解决问题吗?我正在尝试这些 JAXBContext :: newInstance 变体的原因是我偶然发现了这个问题,其中接受的答案包括基于个别类而不是对象工厂构建JAXB上下文选项。我正在使用的示例 a.xml JAXB Java代码在帖子的末尾跟随。

Can anyone shed some light? The reason I am experimenting on these JAXBContext::newInstance variations is that I've stumbled on this problem where the accepted answer included the option of "building the JAXB context based on individual classes rather than object factories". The sample a.xml and the JAXB Java code I am using follow at the end of the post.

<?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>



JAXB解析代码



JAXB parsing code

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() );
}


推荐答案

生成的JAXB模型来自XML Schema

从XML模式生成的模型创建 JAXBContext 时,我始终建议在生成的类的包名上执行此操作。

When creating a JAXBContext from a model generated from an XML schema I always recommend doing it on the package name of the generated classes.

JAXBContext jc = JAXBContext.newInstance("example.a");

使用 newInstance 更好采用 ClassLoader 参数的方法。当您从Java SE迁移到Java EE环境时,这将为您带来悲伤。

It is even better to use a newInstance method that takes a ClassLoader parameter. This will save you grief when you move from a Java SE to Java EE environment.

JAXBContext jc = JAXBContext.newInstance("example.a", example.a.ObjectFactory.class.getClassLoader());

在包上创建 JAXBContext 时名称,JAXB impl假定您从XML模式生成模型并引入 ObjectFactory 类,因为它始终生成使用 @XmlRegistry <注释的类/ code>使用此名称。

When you create the JAXBContext on the package name, the JAXB impl assumes you generated the model from an XML schema and pulls in the ObjectFactory class since it always generates the class annotated with @XmlRegistry with this name.

从Java模型开始

这时我建议人们使用带有类的 newInstance 方法。从JAXB类引导 JAXBContext 时,对于名为 ObjectFactory 的类没有什么特别之处。任何使用 @XmlRegistry 注释的类都可以扮演 ObjectFactory 的角色,因此不会自动查找。这就是为什么当你明确地引用 ObjectFactory 时你的用例有效,而当你没有引用时失败。

This is when I recommend people use the newInstance methods that take classes. When bootstrapping a JAXBContext from JAXB classes there is nothing special about a class called ObjectFactory. The role of the ObjectFactory could be played by any class annotated with @XmlRegistry so it is not automatically looked for. This is why your use case worked when you explictly reference ObjectFactory and failed when you did not.

这篇关于JAXBContext.newInstance变体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆