Module  java.xml.bind
软件包  javax.xml.bind

Class JAXBContext



  • public abstract class JAXBContext
    extends Object
    JAXBContext类为客户端提供了JAXB API的入口点。 它提供了管理实现JAXB绑定框架操作所必需的XML / Java绑定信息的抽象:unmarshal,marshal和validate。

    客户端应用程序通常使用newInstance方法的这两种样式之一获取此类的新实例,尽管还有其他专门的方法可用:

    以下JAXB 1.0要求仅适用于模式到java接口/实现绑定。 它不适用于JAXB注释类。 JAXB提供商必须在每个包含模式派生类的包中生成一个jaxb.properties文件。 属性文件必须包含一个名称为javax.xml.bind.context.factory的属性,其值是实现createContext API的类的名称。

    提供商提供的类不必分配给javax.xml.bind.JAXBContext ,它只需要提供一个实现createContext API的类。

    此外,提供者必须在任何客户端调用元组和解组件方法之前调用DatatypeConverter.setDatatypeConverter api。 这是配置在这些操作期间将使用的数据类型转换器所必需的。

    解组

    Unmarshaller类为客户端应用程序提供将XML数据转换为Java内容对象树的功能。 unmarshal方法允许在模式中声明的任何全局XML元素作为实例文档的根解组。 此外,unmarshal方法允许一个无法识别的根元素,其具有xsi:type属性的值,该值将引用在模式中声明的类型定义作为实例文档的根解组。 JAXBContext对象允许在一组模式( contextPath列出)中合并全局元素和类型定义。 由于模式集中的每个模式都可以属于不同的命名空间,因此将模式统一到解组上下文必须与命名空间无关。 这意味着客户端应用程序能够解组出作为contextPath列出的任何模式的实例的XML文档。 例如:

      JAXBContext jc = JAXBContext.newInstance( "com.acme.foo:com.acme.bar" );
          Unmarshaller u = jc.createUnmarshaller();
          FooObject fooObj = (FooObject)u.unmarshal( new File( "foo.xml" ) ); // ok
          BarObject barObj = (BarObject)u.unmarshal( new File( "bar.xml" ) ); // ok
          BazObject bazObj = (BazObject)u.unmarshal( new File( "baz.xml" ) ); // error, "com.acme.baz" not in contextPath 

    客户端应用程序也可以显式生成Java内容树,而不是解组现有的XML数据。 对于所有JAXB注释的值类,应用程序可以使用构造函数创建内容。 对于模式派生的接口/实现类以及未绑定到JAXB注释类的创作元素,应用程序需要有关于每个派生模式的接入和知识ObjectFactory类存在于每个包含在Java包contextPath 对于每个模式派生的java类,都有一个静态工厂方法来生成该类型的对象。 例如,假定在编译模式之后,你有一个包com.acme.foo包含名为架构派生接口PurchaseOrder 为了创建该类型的对象,客户端应用程序将使用如下所示的工厂方法:

      com.acme.foo.PurchaseOrder po =
               com.acme.foo.ObjectFactory.createPurchaseOrder(); 

    一旦客户端应用程序具有模式派生对象的实例,它可以使用mutator方法来设置内容。

    有关生成的ObjectFactory类的更多信息,请参见规范的第4.2节Java包

    提供者必须在每个包中生成一个类,其中包含名为ObjectFactory的包的所有必需的对象工厂方法以及静态的newInstance( javaContentInterface )方法

    编组

    Marshaller类为客户端应用程序提供了将Java内容树转换回XML数据的能力。 编组使用工厂方法手动创建的内容树和编组一个unmarshal操作的结果的内容树之间没有区别。 客户端可以将java内容树编组回到java.io.OutputStreamjava.io.Writer XML数据。 编组过程可以替代地将SAX2事件流生成到注册的ContentHandler或生成DOM节点对象。 客户端应用程序可以控制输出编码,以及是否将XML数据编组为完整文档或作为片段。

    这是一个简单的示例,它解组XML文档,然后将其重新编排出来:

      JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
    
            // unmarshal from foo.xml
            Unmarshaller u = jc.createUnmarshaller();
            FooObject fooObj = (FooObject)u.unmarshal( new File( "foo.xml" ) );
    
            // marshal to System.out
            Marshaller m = jc.createMarshaller();
            m.marshal( fooObj, System.out ); 

    验证

    自JAXB 1.0以来,验证已经发生了重大变化。 Validator类已被弃用,可选。 这意味着建议您不要使用此类,实际上,根据您的JAXB提供程序,可能甚至不可用。 当使用JAXB 1.0运行时系统部署时,依靠Validator JAXB 1.0客户端应用程序仍然可以正常工作。 在JAXB 2.0中, Unmarshaller包含了方便公开JAXP 1.3 javax.xml.validation框架的方法。 有关详细信息,请参阅Unmarshaller.setSchema(javax.xml.validation.Schema) API。

    JAXB运行时绑定框架兼容性

    以下JAXB 1.0限制仅适用于绑定到接口/实现类的模式。 由于此绑定不需要常见的运行时系统,JAXB客户端应用程序不得尝试从不同的提供程序混合运行时对象( JAXBContext, Marshaller等)。 这并不意味着客户端应用程序不可移植,它只是意味着客户端必须使用由用于编译模式的同一提供程序提供的运行时系统。

    发现JAXB实现

    要创建JAXBContext的实例,将调用JAXBContext.newInstance(...)方法之一。 在JAX-B实现被发现之后,呼叫被委派给适当提供者的方法createContext(...)传递来自原始呼叫的参数。

    JAX-B实现发现每次调用JAXBContext.newInstance 如果没有提供用户特定的配置,则必须返回默认的JAX-B提供程序。

    实现发现包括以下步骤:

    1. 明确传递给newInstance(java.lang.String)方法的包/类按照它们指定的顺序进行处理,直到jaxb.properties文件在其包中查找,通过使用关联的类加载器 - 这是the owner class loaderClass参数,而对于包指定ClassLoader

      如果发现这样的资源,它是loaded作为属性文件,并且JAXB_CONTEXT_FACTORY键的值将被假设为提供者工厂类。 如果没有找到值,则使用"javax.xml.bind.context.factory"作为向后兼容性原因的键。 该类然后由上面讨论的关联类加载器加载。

      这个阶段的查找允许一些软件包强制使用某个JAXB实现。 (例如,可能模式编译器已经在代码中生成了一些供应商扩展。)

      此配置方法已弃用。

    2. 如果系统属性JAXB_CONTEXT_FACTORY存在,则其值被假设为提供者工厂类。 如果不存在此类属性,则属性"javax.xml.bind.context.factory""javax.xml.bind.JAXBContext"也被检查(按此顺序),由于向后兼容性原因。 这个查询阶段使得每个JVM覆盖JAXB实现。
    3. JAXBContextFactory的提供商使用由ServiceLoader类定义的服务提供商加载工具来加载,以尝试使用default loading mechanism定位和加载服务的实现 :服务提供商加载工具将使用current thread's context class loader尝试加载上下文厂。 如果上下文类加载器为空,则将使用system class loader
      service configuration error的情况下,将抛出一个JAXBException
    4. 寻找资源/META-INF/services/javax.xml.bind.JAXBContext使用提供的类加载器。 没有类加载器参数的方法使用Thread.currentThread().getContextClassLoader() 如果存在这样的资源,则其内容被认为是提供者工厂类。 此配置方法已弃用。
    5. 最后,如果上述所有步骤失败,那么其余的查找是未指定的。 也就是说,推荐的行为是简单地寻找一些硬编码的平台默认JAXB实现。 这个查询阶段是为了使Java SE能够拥有自己的JAXB实现作为最后的手段。

    一旦发现了提供者工厂类,将上下文创建委托给其中一个createContext(...)方法。 由于向后兼容的原因,有两种方法来实现提供者工厂类:

    1. 该类是实现JAXBContextFactory 它也必须实现no-arg构造函数。 如果在其他步骤中发现,那么3,首先创建使用no-arg构造函数的新实例。 之后,在此实例上调用适当的实例方法。
    2. 该类不是上面的接口的实现,然后它被要求实现以下静态方法签名:
        public static JAXBContext createContext(
                                            String contextPath,
                                            ClassLoader classLoader,
                                            Map<String,Object> properties ) throws JAXBException
      
       public static JAXBContext createContext(
                                            Class[] classes,
                                            Map<String,Object> properties ) throws JAXBException 
      在这种情况下,使用适当的静态方法代替实例方法。 这种方法与ServiceLoader不兼容,因此不能与步骤3一起使用。

    无论使用方法1(JAXBContextFactory)还是使用2(无接口,静态方法),给定方法createContext(...)行为没有差异。

    API Note:
    仅使用资源/META-INF/services/javax.xml.bind.JAXBContext (在步骤4中描述)的服务发现方法仅允许向后兼容性,强烈建议迁移到标准ServiceLoader机制(在步骤3中描述)。 这里的区别是资源名称,不符合服务的类型名称。

    同样使用提供者实现接口JAXBContextFactory是优先于使用定义静态方法,相同于JAXB_CONTEXT_FACTORY属性优于属性"javax.xml.bind.context.factory"

    Implementation Note:
    在最后一步中,如果检测到Glassfish AS环境,则使用其特定的服务装载程序来查找工厂类。
    从以下版本开始:
    1.6,JAXB 1.0
    另请参见:
    MarshallerUnmarshallerS 7.4.1 "Named Packages" in Java Language Specification
    • 字段详细信息

      • JAXB_CONTEXT_FACTORY

        public static final String JAXB_CONTEXT_FACTORY
        包含能够创建新的 JAXBContext对象的类的名称的属性的名称。
        另请参见:
        Constant Field Values
    • 构造方法详细信息

      • JAXBContext

        protected JAXBContext​()
    • 方法详细信息

      • newInstance

        public static JAXBContext newInstance​(String contextPath)
                                       throws JAXBException
        创建一个新的JAXBContext类的实例。

        这是使用当前线程的上下文类加载器调用newInstance(String,ClassLoader)方法的便利方法。

        异常
        JAXBException - 如果在创建JAXBContext时遇到错误
        1. 无法在包中找到ObjectFactory.class或jaxb.index
        2. 在contextPath中包含的全局元素之间的歧义
        3. 无法找到上下文工厂提供程序属性的值
        4. 在相同的contextPath上混合来自不同提供者的模式派生包
        5. 软件包不能打开java.xml.bind模块
      • newInstance

        public static JAXBContext newInstance​(String contextPath,
                                              ClassLoader classLoader)
                                       throws JAXBException
        创建一个新的JAXBContext类的实例。

        客户端应用程序必须提供一个上下文路径,该路径是包含模式派生类和/或完全限定JAXB注释类的分隔的java包名称的冒号(':',\ u003A)列表。 通过每个包生成的ObjectFactory.class,向JAXBContext注册模式派生代码。 除了在上下文路径中列出,程序员注释的JAXB映射类可以列在jaxb.index资源文件中,格式如下所述。 请注意,java包可以包含模式派生类和用户注释的JAXB类。 此外,java包可能包含必须处理的JAXB包注释。 (参见JLS,第7.4.1节“命名包”)。

        contextPath中列出的每个包都必须符合以下一个或两个条件,否则将抛出一个JAXBException

        1. 它必须包含ObjectFactory.class
        2. 它必须包含jaxb.index

        jaxb.index的格式

        该文件包含一个换行的类名列表。 空格和制表符字符以及空白行将被忽略。 注释字符为'#'(0x23); 在每行上,忽略第一个注释字符之后的所有字符。 文件必须以UTF-8编码。 来自列表类的newInstance(Class...)定义的类可以与JAXBContext注册。

        jaxb.index文件中出现的类名的jaxb.index是:

        • 不得以“.class”结尾。
        • 类名相对于包含jaxb.index文件的包解析。 只允许在包含jaxb.index文件的包中直接jaxb.index
        • 不允许使用完全限定的类名。 相对于当前包的限定类名仅允许指定嵌套或内部类。

        为了保持与JAXB 1.0模式到Java接口/实现绑定的兼容性,通过模式定制<jaxb:globalBindings valueClass="false">启用,JAXB提供程序将确保上下文路径中的每个软件包都有一个jaxb.properties文件,其中包含javax.xml.bind.context.factory属性的值,并且所有值都解析为同一供应商。 此要求不适用于JAXB注释类。

        如果在contextPath上列出的各种软件包之间存在任何全局XML元素名称冲突,将抛出一个JAXBException

        在同一上下文路径中混合来自多个JAXB提供程序的生成的接口/ impl绑定可能会导致抛出JAXBException

        发现JAXB实现涉及的步骤在类javadoc中讨论。

        参数
        contextPath - 包含模式派生类和/或Java到模式(JAXB注释)映射类的Java包名称列表。 contextPath中名为模块的软件包必须至少为openjava.xml.bind模块。
        classLoader - 此类加载器将用于定位实现类。
        结果
        一个新的实例 JAXBContext
        异常
        JAXBException - 如果在创建JAXBContext时遇到错误
        1. 无法在包中找到ObjectFactory.class或jaxb.index
        2. 在contextPath中包含的全局元素之间的歧义
        3. 无法找到上下文工厂提供程序属性的值
        4. 在相同的contextPath上混合来自不同提供者的模式派生包
        5. 软件包不能打开java.xml.bind模块
      • newInstance

        public static JAXBContext newInstance​(String contextPath,
                                              ClassLoader classLoader,
                                              Map<String,?> properties)
                                       throws JAXBException
        创建一个新的JAXBContext类的实例。

        这与newInstance(String, ClassLoader)大致相同,但此版本允许您传递提供者特定的属性来配置JAXBContext的实例化。

        属性的解释取决于实现。 如果找到不了解的属性,那么实现必须抛出JAXBException

        参数
        contextPath - 包含模式派生类和/或Java到模式(JAXB注释)映射类的Java包名称列表。 在包contextPath是在一个名为模块必须open到至少java.xml.bind模块。
        classLoader - 此类加载器将用于定位实现类。
        properties - 提供者特定的属性。 可以是null,这意味着与传递一个空的地图相同的东西。
        结果
        一个新的实例 JAXBContext
        异常
        JAXBException - 如果在创建JAXBContext时遇到错误
        1. 无法在包中找到ObjectFactory.class或jaxb.index
        2. 在contextPath中包含的全局元素之间的歧义
        3. 无法找到上下文工厂提供程序属性的值
        4. 在相同的contextPath上混合来自不同提供者的模式派生包
        5. 软件包不能打开java.xml.bind模块
        从以下版本开始:
        1.6,JAXB 2.0
      • newInstance

        public static JAXBContext newInstance​(Class<?>... classesToBeBound)
                                       throws JAXBException
        创建一个新的JAXBContext类的实例。

        客户端应用程序必须提供新的上下文对象需要识别的类的列表。 不仅新的上下文将识别所有指定的类,而且还将识别从指定的类静态地直接/间接引用的任何类。 被引用的类的子类也没有@XmlTransient引用的类被注册到JAXBContext。 例如,在以下Java代码中,如果您做了newInstance(Foo.class) ,则新创建的JAXBContext将识别FooBar ,但不能ZotFooBar

          class Foo {
              @XmlTransient FooBar c;
              Bar b;
         }
         class Bar { int x; }
         class Zot extends Bar { int y; }
         class FooBar { } 
        因此,典型的客户端应用程序只需要指定顶级类,但需要注意。

        请注意,对于JAXBContext注册的每个java包,当可选包注释存在时,都必须处理它们。 (参见JLS,第7.4.1节“命名包”)。

        发现JAXB实现涉及的步骤在类javadoc中讨论。

        参数
        classesToBeBound - 由新的JAXBContext识别的java类的列表。 在命名模块中的classesToBeBound中的类必须至少为java.xml.bind模块的包中为open 可以是空的,在这种情况下,只有知道定义类的JAXBContext才会被返回。
        结果
        一个新的实例 JAXBContext
        异常
        JAXBException - 如果在创建JAXBContext时遇到错误,例如(但不限于):
        1. 没有发现JAXB实现
        2. 类使用JAXB注释不正确
        3. 类具有冲突注释(即,具有相同类型名称的两个类)
        4. JAXB实现无法找到提供程序特定的带外信息(例如在开发时生成的附加文件)。
        5. classesToBeBound不能打开java.xml.bind模块
        IllegalArgumentException - 如果参数包含 null (即 newInstance(null);
        从以下版本开始:
        1.6,JAXB 2.0
      • newInstance

        public static JAXBContext newInstance​(Class<?>[] classesToBeBound,
                                              Map<String,?> properties)
                                       throws JAXBException
        创建一个JAXBContext类的新实例。

        newInstance(Class...)的超载配置为此实例化的“属性” JAXBContext

        属性的解释取决于实现。 如果找到不了解的属性,那么实现必须抛出JAXBException

        参数
        classesToBeBound - 由新的JAXBContext识别的java类的列表。 在名称模块中的classesToBeBound中的类必须至少为java.xml.bind模块的包中为open 可以是空的,在这种情况下,只有知道规范定义类的JAXBContext才会被返回。
        properties - 提供者特定的属性。 可以是null,这意味着与传递一个空的地图相同的东西。
        结果
        一个新的实例 JAXBContext
        异常
        JAXBException - 如果在创建JAXBContext时遇到错误,例如(但不限于):
        1. 没有发现JAXB实现
        2. 类使用JAXB注释不正确
        3. 类具有冲突注释(即,具有相同类型名称的两个类)
        4. JAXB实现无法找到提供程序特定的带外信息(例如在开发时生成的附加文件)。
        5. classesToBeBound不能打开java.xml.bind模块
        IllegalArgumentException - 如果参数包含 null (即 newInstance(null,someMap);
        从以下版本开始:
        1.6,JAXB 2.0
      • createUnmarshaller

        public abstract Unmarshaller createUnmarshaller​()
                                                 throws JAXBException
        创建可用于将XML数据转换为java内容树的 Unmarshaller对象。
        结果
        一个 Unmarshaller对象
        异常
        JAXBException - 如果在创建 Unmarshaller对象时遇到错误
      • createMarshaller

        public abstract Marshaller createMarshaller​()
                                             throws JAXBException
        创建可用于将java内容树转换为XML数据的 Marshaller对象。
        结果
        一个 Marshaller对象
        异常
        JAXBException - 如果在创建 Marshaller对象时遇到错误
      • createValidator

        @Deprecated
        public abstract Validator createValidator​()
                                           throws JAXBException
        已过时。 自JAXB2.0起
        在JAXB 2.0中,已经使用了Validator作为可选的和不推荐的。 有关详细信息,请参阅javadoc for Validator

        创建一个Validator对象,该对象可用于根据其源模式验证java内容树。

        结果
        一个 Validator对象
        异常
        JAXBException - 如果在创建 Validator对象时遇到错误
      • createBinder

        public <T> Binder<T> createBinder​(Class<T> domType)
        创建可用于关联/就地解组/编组的 Binder对象。
        参数
        domType - 通过传入其DOM Node类来选择要使用的DOM API。
        结果
        总是一个新的有效的 Binder对象。
        异常
        UnsupportedOperationException - 如果实现不支持对应于 domType DOM API。
        从以下版本开始:
        1.6,JAXB 2.0
      • createBinder

        public Binder<Node> createBinder​()
        为W3C DOM创建一个 Binder
        结果
        总是一个新的有效的 Binder对象。
        从以下版本开始:
        1.6,JAXB 2.0
      • createJAXBIntrospector

        public JAXBIntrospector createJAXBIntrospector​()
        创建一个可用于内省JAXB对象的 JAXBIntrospector对象。
        结果
        总是返回一个非空的有效 JAXBIntrospector对象。
        异常
        UnsupportedOperationException - 在JAXB 1.0实现上调用此方法将抛出UnsupportedOperationException UnsupportedOperationException
        从以下版本开始:
        1.6,JAXB 2.0