Java 中文官方教程 2022 版(四十九)(2)

简介: Java 中文官方教程 2022 版(四十九)

Java 中文官方教程 2022 版(四十九)(1)https://developer.aliyun.com/article/1488526

基本示例

原文:docs.oracle.com/javase/tutorial/jaxb/intro/basic.html

本节描述了基本的 JAXB 示例(修改 Marshal、Unmarshal Validate),演示了如何:

  • 将 XML 文档解组为 Java 内容树,并访问其中包含的数据。
  • 修改 Java 内容树。
  • 使用 ObjectFactory 类创建 Java 内容树,然后将其编组为 XML 数据。
  • 在解组期间执行验证。
  • 在运行时验证 Java 内容树。

修改 Marshal 示例

修改 Marshal 示例演示了如何修改 Java 内容树。

  1. jaxb-ri-install/samples/modify-marshal/src/Main.java 类声明导入了三个标准 Java 类,五个 JAXB 绑定框架类和 primer.po 包:
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import primer.po.*;
  1. 创建一个用于处理在 primer.po 中生成的类的 JAXBContext 实例。
JAXBContext jc = JAXBContext.newInstance( "primer.po" );
  1. 创建一个 Unmarshaller 实例,并解组 po.xml 文件。
Unmarshaller u = jc.createUnmarshaller();
PurchaseOrder po = (PurchaseOrder)
    u.unmarshal(new FileInputStream("po.xml"));
  1. 使用 set 方法修改内容树中 address 分支中的信息。
USAddress address = po.getBillTo();
address.setName("John Bob");
address.setStreet("242 Main Street");
address.setCity("Beverly Hills");
address.setState("CA");
address.setZip(new BigDecimal
address.setName("John Bob");
address.setStreet("242 Main Street");
address.setCity("Beverly Hills");
address.setState("CA");
address.setZip(new BigDecimal("90210"));
  1. 创建一个 Marshaller 实例,并将更新后的 XML 内容编组到 system.out。使用 setProperty API 指定输出编码;在本例中为格式化(易读)的 XML。
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(po, System.out);

使用 Ant 构建和运行修改 Marshal 示例

要使用 Ant 编译和运行修改 Marshal 示例,在终端窗口中,转到 jaxb-ri-install/samples/modify-marshal/ 目录,并输入以下内容:

ant

Unmarshal Validate 示例

Unmarshal Validate 示例演示了如何在解组期间启用验证。请注意,JAXB 提供了在解组期间进行验证但不在编组期间进行验证的功能。有关验证的更多详细信息,请参阅更多关于验证。

  1. jaxb-ri-install/samples/unmarshal-validate/src/Main.java 类声明导入了一个标准 Java 类,十一个 JAXB 绑定框架类和 primer.po 包:
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.ValidationEventLocator;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Schema;
import primer.po.*;
  1. 创建一个用于处理在 primer.po 包中生成的类的 JAXBContext 实例。
JAXBContext jc = JAXBContext.newInstance("primer.po");
  1. 创建一个 Unmarshaller 实例。
Unmarshaller u = jc.createUnmarshaller();
  1. 默认的 JAXB Unmarshaller ValidationEventHandler 已启用,以将验证警告和错误发送到 system.out。默认配置导致在遇到第一个验证错误时解组操作失败。
u.setValidating( true );
  1. 尝试将 po.xml 文件解组为 Java 内容树。在此示例中,po.xml 文件包含一个故意的错误。
PurchaseOrder po = (PurchaseOrder)u.unmarshal(
    new FileInputStream("po.xml"));
  1. 默认验证事件处理程序处理验证错误,生成输出到 system.out,然后抛出异常。
} catch( UnmarshalException ue ) {
    System.out.println("Caught UnmarshalException");
} catch( JAXBException je ) { 
    je.printStackTrace();
} catch( IOException ioe ) {
    ioe.printStackTrace();
}

使用 Ant 构建和运行 Unmarshal Validate 示例。

要使用 Ant 编译和运行 Unmarshal Validate 示例,在终端窗口中,转到 jaxb-ri-install/samples/unmarshal-validate/ 目录,并输入以下内容:

ant 

自定义 JAXB 绑定

原文:docs.oracle.com/javase/tutorial/jaxb/intro/custom.html

以下部分描述了几个示例,这些示例是基于基本示例中演示的概念构建的。

本节的目标是演示如何使用自定义绑定声明来自定义 JAXB 绑定,可以通过以下两种方式之一进行:

  • 作为内联注释在 XML 模式中
  • 作为传递给 JAXB 绑定编译器的外部文件中的语句

与基本 JAXB 示例中的示例不同,该示例侧重于在生成基于模式的 Java 绑定类之前对 XML 模式进行的自定义。


注意: JAXB 绑定自定义目前必须手动完成。JAXB 技术的目标之一是标准化绑定声明的格式,从而可以创建自定义工具,并在 JAXB 实现之间提供标准的交换格式。


本节介绍了可以对 JAXB 绑定和验证方法进行的自定义。更多信息,请参见JAXB 规范

为什么要自定义?

在大多数情况下,由 JAXB 绑定编译器生成的默认绑定就足够了。然而,有些情况下,您可能希望修改默认绑定。其中一些情况包括:

  • 为基于模式的 JAXB 包、类、方法和常量创建 API 文档:通过向您的模式添加自定义 Javadoc 工具注释,您可以解释与您的实现特定的概念、指南和规则。
  • 为默认的 XML 名称到 Java 标识符映射无法自动处理的情况提供语义上有意义的自定义名称;例如:
  • 为解决名称冲突(如 JAXB 规范 的附录 D.2.1 中所述)。请注意,JAXB 绑定编译器会检测并报告所有名称冲突。
  • 为类型安全枚举常量提供名称,这些名称不是有效的 Java 标识符;例如,枚举整数值。
  • 为未命名模型组的 Java 表示提供更好的名称,当它们绑定到 Java 属性或类时。
  • 提供比默认从目标命名空间 URI 派生的包名称更有意义的名称。
  • 覆盖默认绑定;例如:
  • 指定模型组必须绑定到类而不是列表。
  • 指定一个固定属性可以绑定到一个 Java 常量。
  • 覆盖 XML 模式内置数据类型到 Java 数据类型的指定默认绑定。在某些情况下,您可能希望引入一个替代的 Java 类,该类可以表示内置 XML 模式数据类型的其他特征。

自定义概述

本节解释了一些核心的 JAXB 自定义概念:

  • 内联和外部自定义
  • 范围、继承和优先级
  • 自定义语法
  • 定制命名空间前缀

内联和外部定制

对默认 JAXB 绑定的定制以传递给 JAXB 绑定编译器的绑定声明的形式进行。这些绑定声明可以通过以下两种方式进行:

  • 作为源 XML 模式中的内联注释
  • 作为外部绑定定制文件中的声明

对于一些人来说,使用内联定制更容易,因为您可以在应用于的模式的上下文中看到您的定制。相反,使用外部绑定定制文件使您能够定制 JAXB 绑定而无需修改源模式,并且使您能够轻松地将定制应用于多个模式文件。


注意: 您可以结合两种类型的定制。例如,您可以在内联注释中包含对外部绑定定制文件的引用。但是,您不能在同一模式元素上同时声明内联和外部定制。


这些类型的定制在以下各节中有更详细的描述:

内联定制

通过在 XML 模式文件中使用内联绑定声明进行的 JAXB 绑定定制采用了嵌入在模式元素中的元素的形式(xsd:是 XML 模式命名空间前缀,在 W3C XML Schema Part 1: Structures中定义)。内联定制的一般形式如下例所示:

<xs:annotation>
    <xs:appinfo>
        <!--
        ...
        binding declarations     .
        ...
        -->
    </xs:appinfo>
</xs:annotation>

定制是应用在模式中声明的位置。例如,对特定元素级别的声明仅适用于该元素。请注意,必须在声明标签中使用 XML 模式命名空间前缀。在前面的例子中,xs:被用作命名空间前缀,因此声明被标记为

外部绑定定制文件

通过使用包含绑定声明的外部文件进行的 JAXB 绑定定制,采用了以下示例中显示的一般形式:

<jxb:bindings schemaLocation = "xs:anyURI">
    <jxb:bindings node = "xs:string">*
        <!-- binding declaration -->
    <jxb:bindings>
</jxb:bindings>
  • schemaLocation是指向远程模式的 URI 引用。
  • node是一个 XPath 1.0 表达式,用于标识与给定绑定声明相关联的schemaLocation中的模式节点。

例如,在 JAXB 绑定声明文件中,第一个schemaLocation/node声明指定了模式名称和根模式节点:

<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">
</jxb:bindings>

后续的schemaLocation/node声明,例如前一个模式示例中名为ZipCodeTypesimpleType元素,采用以下形式:

<jxb:bindings node="//xs:simpleType [@name=’ZipCodeType’]">

绑定定制文件格式

绑定定制文件必须是 ASCII 文本。名称或扩展名并不重要;尽管在本章中使用的典型扩展名是.xjb

将定制文件传递给 JAXB 绑定编译器

包含绑定声明的定制文件通过以下语法传递给 JAXB 绑定编译器xjc

xjc -b file schema

其中file是绑定自定义文件的名称,schema是要传递给绑定编译器的模式的名称。

您可以拥有一个包含多个模式的自定义的单个绑定文件,或者您可以将自定义分成多个绑定文件;例如:

xjc schema1.xsd schema2.xsd schema3.xsd \
    -b bindings123.xjb
xjc schema1.xsd schema2.xsd schema3.xsd \
    -b bindings1.xjb \
    -b bindings2.xjb \
    -b bindings3.xjb

请注意,命令行上模式文件和绑定文件的顺序无关紧要;尽管每个绑定自定义文件在命令行上必须在其自己的-b开关之前。

有关xjc编译器选项的更多信息,请参见 JAXB 编译器选项。

外部绑定自定义的限制

有几条规则适用于在外部绑定自定义文件中进行的绑定声明,而不适用于在源模式中内联进行的类似声明:

  • 绑定自定义文件必须以jxb:bindings version属性开头,以及 JAXB 和 XMLSchema 命名空间的属性:
<jxb:bindings version="1.0" 
    >
  • 绑定声明适用的远程模式必须通过使用jxb:bindings声明明确在 XPath 表示法中标识,指定schemaLocationnode属性:
  • schemaLocation指定远程模式的 URI 引用。
  • node指定一个 XPath 1.0 表达式,用于标识schemaLocation中的模式节点,给定的绑定声明与之相关联;在绑定自定义文件中的初始jxb:bindings声明的情况下,此节点通常为"/xs:schema"

同样,必须使用 XPath 表示法指定要应用自定义的模式中的各个节点;例如:

<jxb:bindings node="//xs:complexType [@name=’USAddress’]">

在这种情况下,绑定编译器将自定义应用于节点,就好像声明被嵌入在节点的元素中一样。

总结这些规则,外部绑定元素仅在以下三种情况下被 JAXB 绑定编译器识别并处理:

  • 当其父元素是元素时。
  • 当它是另一个元素的祖先时。
  • 当它是文档的根元素时。将元素作为其根的 XML 文档称为外部绑定声明文件。

范围、继承和优先级

默认的 JAXB 绑定可以在四个不同级别或范围上进行自定义或覆盖。

以下图示了自定义声明的继承和优先级。具体来说,金字塔顶部的声明继承并取代下面的声明。

组件声明继承并取代定义声明;定义声明继承并取代模式声明;模式声明继承并取代全局声明。

图:自定义范围继承和优先级


自定义语法

JAXB 绑定声明的四种类型的语法,XML 到 Java 数据类型绑定声明的语法,以及自定义命名空间前缀的语法在以下部分中描述。

  • 全局绑定声明
  • 模式绑定声明
  • 类绑定声明
  • 属性绑定声明
  • javaType 绑定声明
  • Typesafe 枚举绑定声明
  • javadoc 绑定声明

全局绑定声明

全局范围的自定义使用 声明。全局范围自定义的语法如下:

<globalBindings>
    [ collectionType = "collectionType" ]
    [ fixedAttributeAsConstantProperty = "true" | "false" | "1" | "0" ]
    [ generateIsSetMethod = "true" | "false" | "1" | "0" ]
    [ enableFailFastCheck = "true" | "false" | "1" | "0" ]
    [ choiceContentProperty = "true" | "false" | "1" | "0" ]
    [ underscoreBinding = "asWordSeparator" | "asCharInWord" ]
    [ typesafeEnumBase = "typesafeEnumBase" ]
    [ typesafeEnumMemberName = "generateName" | "generateError" ]
    [ enableJavaNamingConventions = "true" | "false" 
    | "1" | "0" ]
    [ bindingStyle = "elementBinding" | "modelGroupBinding" ]
    [ <javaType> ... </javaType> ]*
</globalBindings>
  • collectionType 可以是 indexed 或实现 java.util.List 的任何完全限定类名。
  • fixedAttributeAsConstantProperty 可以是 true, false, 1, 或 0。默认值为 false
  • generateIsSetMethod 可以是 true, false, 1, 或 0。默认值为 false
  • enableFailFastCheck 可以是 true, false, 1, 或 0。如果 enableFailFastChecktrue1,并且 JAXB 实现支持此可选检查,那么在设置属性时将执行类型约束检查。默认值为 false。请注意,JAXB 实现不支持快速失败验证。
  • choiceContentProperty 可以是 true, false, 1, 或 0。默认值为 false。当 bindingStyleelementBinding 时,choiceContentProperty 不相关。因此,如果指定 bindingStyleelementBinding,那么 choiceContentProperty 必须导致无效的自定义。
  • underscoreBinding 可以是 asWordSeparatorasCharInWord。默认值为 asWordSeparator
  • typesafeEnumBase 可以是一组 QNames,每个都必须解析为简单类型定义。默认值为 xs:NCName。有关将 simpleType 定义本地化映射到 Java typesafe enum 类的信息,请参见 Typesafe 枚举绑定声明。
  • typesafeEnumMemberName 可以是 generateErrorgenerateName。默认值为 generateError
  • enableJavaNamingConventions 可以是 true, false, 1, 或 0。默认值为 true
  • bindingStyle 可以是 elementBindingmodelGroupBinding。默认值为 elementBinding
  • 可以是零个或多个 javaType 绑定声明。有关更多信息,请参见 javaType 绑定声明。

声明仅在顶层 schema 元素的 annotation 元素中有效。在任何给定的模式或绑定声明文件中只能有一个 声明的实例。如果一个源模式包含或导入第二个源模式,则 声明必须在第一个源模式中声明。

模式绑定声明

模式范围的自定义使用 声明。模式范围自定义的语法如下:

<schemaBindings>
[ <package> package </package> ]
[ <nameXmlTransform> ... </nameXmlTransform> ]*
</schemaBindings>
<package 
    [ name = "packageName" ]
    [ <javadoc> ... </javadoc> ]
</package>
<nameXmlTransform>
[ <typeName 
    [ suffix="suffix" ]
    [ prefix="prefix" ] /> ]
[ <elementName 
    [ suffix="suffix" ]
    [ prefix="prefix" ] /> ]
[ <modelGroupName 
    [ suffix="suffix" ]
    [ prefix="prefix" ] /> ]
[ <anonymousTypeName 
    [ suffix="suffix" ]
    [ prefix="prefix" ] /> ]
</nameXmlTransform>

如上所示, 声明包括两个子组件:

  • ... 指定了包的名称,如果需要的话,还可以指定模式派生类的 API 文档的位置。
  • ... 指定要应用的自定义。

类绑定声明

绑定声明使您能够自定义模式元素与 Java 内容接口或 Java Element 接口的绑定。 声明可用于自定义:

  • 用于模式派生的 Java 接口的名称
  • 用于模式派生的 Java 内容接口的实现类

自定义的语法是:

<class 
    [ name = "className"]
    [ implClass= "implClass" ] >
    [ <javadoc> ... </javadoc> ]
</class>
  • name 是派生 Java 接口的名称。它必须是有效的 Java 接口名称,不能包含包前缀。包前缀从当前包的值继承。
  • implClassclassName 的实现类的名称,必须包含完整的包名称。
  • 元素为模式派生的 Java 接口指定了 Javadoc 工具注释。在此输入的字符串必须使用 CDATA< 来转义嵌入的 HTML 标记。

属性绑定声明

绑定声明使您能够自定义 XML 模式元素与其 Java 表示作为属性的绑定。自定义的范围可以是在定义级别或组件级别,具体取决于 绑定声明的指定位置。

自定义的语法是:

<property
    [ name = "propertyName"]
    [ collectionType = "propertyCollectionType" ]
    [ fixedAttributeAsConstantProperty = "true" |
    "false" | "1" | "0" ]
    [ generateIsSetMethod = "true" | 
    "false" | "1" | "0" ]
    [ enableFailFastCheck ="true" | 
    "false" | "1" | "0" ]
    [ <baseType> ... </baseType> ]
    [ <javadoc> ... </javadoc> ]
</property>
<baseType>
    <javaType> ... </javaType>
</baseType>
  • name 定义了自定义值 propertyName;它必须是有效的 Java 标识符。
  • collectionType 定义了自定义值 propertyCollectionType,即属性的集合类型 propertyCollectionType。如果指定,属性可以是 indexed 或任何实现 java.util.List 的完全限定类名。
  • fixedAttributeAsConstantProperty 定义了自定义值 fixedAttributeAsConstantProperty。该值可以是 truefalse10
  • generateIsSetMethod 定义了自定义值 generateIsSetMethod。该值可以是 truefalse10
  • enableFailFastCheck 定义了自定义值 enableFailFastCheck。该值可以是 truefalse10。请注意,JAXB 实现不支持快速失败验证。
  • 自定义了属性的 getter 方法的 Javadoc 工具注释。

Java 中文官方教程 2022 版(四十九)(3)https://developer.aliyun.com/article/1488535

相关文章
|
3天前
|
Java 开发者 UED
【实战宝典】Java异常处理大师级教程:throws关键字,让异常声明成为你的专属标签!
【实战宝典】Java异常处理大师级教程:throws关键字,让异常声明成为你的专属标签!
16 3
|
15天前
|
前端开发 Java Maven
【前端学java】全网最详细的maven安装与IDEA集成教程!
【8月更文挑战第12天】全网最详细的maven安装与IDEA集成教程!
37 2
【前端学java】全网最详细的maven安装与IDEA集成教程!
|
4天前
|
Java 开发者
Java多线程教程:使用ReentrantLock实现高级锁功能
Java多线程教程:使用ReentrantLock实现高级锁功能
14 1
|
21天前
|
存储 网络协议 Oracle
java教程
java教程【8月更文挑战第11天】
19 5
|
2天前
|
Java API
Java与Lua互相调用简单教程
【8月更文挑战第29天】在软件开发中,Java以其强大的稳定性和广泛的生态系统著称,而Lua则因其轻量级、灵活和嵌入式的特点在脚本编写、游戏开发等领域大放异彩。将两者结合使用,可以充分利用Java的底层能力和Lua的快速开发优势。本文将通过一个简单的教程,介绍如何在Java程序中嵌入并执行Lua脚本,以及如何在Lua中调用Java方法。
9 0
|
2月前
|
SQL 安全 Java
「滚雪球学Java」教程导航帖(更新2024.07.16)
《滚雪球学Spring Boot》是一个面向初学者的Spring Boot教程,旨在帮助读者快速入门Spring Boot开发。本专通过深入浅出的方式,将Spring Boot开发中的核心概念、基础知识、实战技巧等内容系统地讲解,同时还提供了大量实际的案例,让读者能够快速掌握实用的Spring Boot开发技能。本书的特点在于注重实践,通过实例学习的方式激发读者的学习兴趣和动力,并引导读者逐步掌握Spring Boot开发的实际应用。
56 1
「滚雪球学Java」教程导航帖(更新2024.07.16)
WXM
|
2月前
|
Oracle Java 关系型数据库
Java JDK下载安装及环境配置超详细图文教程
Java JDK下载安装及环境配置超详细图文教程
WXM
180 3
|
2月前
|
测试技术 API Android开发
《手把手教你》系列基础篇(九十七)-java+ selenium自动化测试-框架设计篇-Selenium方法的二次封装和页面基类(详解教程)
【7月更文挑战第15天】这是关于自动化测试框架中Selenium API二次封装的教程总结。教程中介绍了如何设计一个支持不同浏览器测试的页面基类(BasePage),该基类包含了对Selenium方法的二次封装,如元素的输入、点击、清除等常用操作,以减少重复代码。此外,页面基类还提供了获取页面标题和URL的方法。
48 2
|
2月前
|
Web App开发 XML Java
《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)
【7月更文挑战第14天】这篇教程介绍了如何使用Java和Selenium构建一个支持跨浏览器测试的自动化测试框架。设计的核心是通过读取配置文件来切换不同浏览器执行测试用例。配置文件中定义了浏览器类型(如Firefox、Chrome)和测试服务器的URL。代码包括一个`BrowserEngine`类,它初始化配置数据,根据配置启动指定的浏览器,并提供关闭浏览器的方法。测试脚本`TestLaunchBrowser`使用`BrowserEngine`来启动浏览器并执行测试。整个框架允许在不同浏览器上运行相同的测试,以确保兼容性和一致性。
51 3
|
2月前
|
存储 Web App开发 Java
《手把手教你》系列基础篇(九十五)-java+ selenium自动化测试-框架之设计篇-java实现自定义日志输出(详解教程)
【7月更文挑战第13天】这篇文章介绍了如何在Java中创建一个简单的自定义日志系统,以替代Log4j或logback。
196 5
下一篇
云函数