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

相关文章
|
7天前
|
Web App开发 JavaScript 前端开发
《手把手教你》系列技巧篇(三十九)-java+ selenium自动化测试-JavaScript的调用执行-上篇(详解教程)
【5月更文挑战第3天】本文介绍了如何在Web自动化测试中使用JavaScript执行器(JavascriptExecutor)来完成Selenium API无法处理的任务。首先,需要将WebDriver转换为JavascriptExecutor对象,然后通过executeScript方法执行JavaScript代码。示例用法包括设置JS代码字符串并调用executeScript。文章提供了两个实战场景:一是当时间插件限制输入时,用JS去除元素的readonly属性;二是处理需滚动才能显示的元素,利用JS滚动页面。还给出了一个滚动到底部的代码示例,并提供了详细步骤和解释。
32 10
|
7天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)
【4月更文挑战第28天】本文简要介绍了自动化测试的实战应用,通过一个在线问卷调查(&lt;https://www.sojump.com/m/2792226.aspx/&gt;)为例,展示了如何遍历并点击问卷中的选项。测试思路包括找到单选和多选按钮的共性以定位元素,然后使用for循环进行点击操作。代码设计方面,提供了Java+Selenium的示例代码,通过WebDriver实现自动答题。运行代码后,可以看到控制台输出和浏览器的相应动作。文章最后做了简单的小结,强调了本次实践是对之前单选多选操作的巩固。
26 0
|
1天前
|
搜索推荐 Java 测试技术
《手把手教你》系列技巧篇(五十)-java+ selenium自动化测试-字符串操作-上篇(详解教程)
【5月更文挑战第14天】本文介绍了自动化测试中如何从字符串中提取特定信息,主要讲解了两种方法:正则表达式和字符串切片操作。文章提供了一个测试场景,即在搜索引擎中搜索“北京宏哥”并比较百度和必应的搜索结果数量。通过字符串切片函数`split()`,可以从搜索结果的描述中提取出数字。代码示例展示了如何使用Java实现这个功能,包括在百度和必应的搜索页面获取结果数量,并进行比较。文章最后还简单提到了其他字符串截取的方法,如`substring()`和`StringUtils`类中的方法。
12 2
|
2天前
|
JavaScript 前端开发 Java
《手把手教你》系列技巧篇(四十九)-java+ selenium自动化测试-隐藏元素定位与操作(详解教程)
【5月更文挑战第13天】本文主要讨论了在Selenium自动化测试中如何处理前端隐藏元素的问题。隐藏元素通常是通过`type="hidden"`或`style="display: none;"`属性实现的,它们在页面上不可见,但仍然存在于HTML代码中。Selenium可以定位到这些隐藏元素,但无法直接进行点击、输入等操作,会报错“ElementNotInteractableException”。
24 3
|
3天前
|
JavaScript 前端开发 测试技术
《手把手教你》系列技巧篇(四十八)-java+ selenium自动化测试-判断元素是否可操作(详解教程)
【5月更文挑战第12天】本文介绍了WebDriver中用于判断元素状态的三个方法:`isEnabled()`、`isSelected()`和`isDisplayed()`。`isSelected()`检查元素是否被选中,通常用于勾选框。`isDisplayed()`则用来判断元素是否在页面上可见。`isEnabled()`方法确定元素是否可操作,例如是否能点击或输入内容。
13 1
|
4天前
|
存储 JavaScript Java
《手把手教你》系列技巧篇(四十七)-java+ selenium自动化测试-判断元素是否显示(详解教程)
【5月更文挑战第11天】WebDriver 的 `isDisplayed()` 方法用于检查页面元素是否可见,如果元素存在于DOM中且可视,返回`true`,否则返回`false`。在自动化测试中,这个方法常用于验证元素是否真正显示在页面上。示例代码展示了如何使用 `isDisplayed()` 判断百度登录页面的特定错误提示文字是否出现。
15 1
|
5天前
|
JavaScript Java 测试技术
《手把手教你》系列技巧篇(四十六)-java+ selenium自动化测试-web页面定位toast-下篇(详解教程)
【5月更文挑战第10天】本文介绍了使用Java和Selenium进行Web自动化测试的实践,以安居客网站为例。最后,提到了在浏览器开发者工具中调试和观察页面元素的方法。
18 2
|
5天前
|
算法 Java Python
保姆级Java入门练习教程,附代码讲解,小白零基础入门必备
保姆级Java入门练习教程,附代码讲解,小白零基础入门必备
|
6天前
|
Web App开发 JavaScript 测试技术
《手把手教你》系列技巧篇(四十五)-java+ selenium自动化测试-web页面定位toast-上篇(详解教程)
【5月更文挑战第9天】本文介绍了在Appium中处理App自动化测试中遇到的Toast元素定位的方法。Toast在Web UI测试中也常见,通常作为轻量级反馈短暂显示。文章提供了两种定位Toast元素的技巧.
12 0
|
7天前
|
Web App开发 缓存 前端开发
《手把手教你》系列技巧篇(四十四)-java+ selenium自动化测试-处理https 安全问题或者非信任站点-下篇(详解教程)
【5月更文挑战第8天】这篇文档介绍了如何在IE、Chrome和Firefox浏览器中处理不信任证书的问题。作者北京-宏哥分享了如何通过编程方式跳过浏览器的证书警告,直接访问不受信任的HTTPS网站。文章分为几个部分,首先简要介绍了问题背景,然后详细讲解了在Chrome浏览器中的两种方法,包括代码设计和运行效果,并给出了其他浏览器的相关信息和参考资料。最后,作者总结了处理此类问题的一些通用技巧。
16 2