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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Java 中文官方教程 2022 版(四十九)

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

javaType 绑定声明

声明提供了一种自定义将 XML 数据类型转换为 Java 数据类型的方法。XML 提供的数据类型比 Java 更多,因此当默认的 JAXB 绑定无法充分表示您的模式时, 声明使您能够指定自定义数据类型绑定。

目标 Java 数据类型可以是 Java 内置数据类型或特定于应用程序的 Java 数据类型。如果将特定于应用程序的 Java 数据类型用作目标,则您的实现还必须为解组和组合数据提供解析和打印方法。为此,JAXB 规范支持 parseMethodprintMethod

  • parseMethod 在解组过程中被调用,将输入文档中的字符串转换为目标 Java 数据类型的值。
  • 在组合过程中,printMethod 被调用以将目标类型的值转换为词法表示。

如果您更喜欢定义自己的数据类型转换,JAXB 定义了一个静态类 DatatypeConverter,以帮助解析和打印 XML Schema 内置数据类型的有效词法表示。

自定义的语法为:

<javaType name= "*javaType*"
    [ xmlType= "*xmlType*" ]
    [ hasNsContext = "true" | "false" ]
    [ parseMethod= "*parseMethod*" ]
    [ printMethod= "*printMethod*" ]>
  • name 是要将 xmlType 绑定到的 Java 数据类型。
  • xmlType 是要将 javaType 绑定到的 XML Schema 数据类型的名称;当 声明的父级为 时,此属性是必需的。
  • hasNsContext 允许指定命名空间上下文作为打印或解析方法的第二个参数;可以是 truefalse10。默认情况下,此属性为 false,在大多数情况下,无需更改。
  • parseMethod 是在解组过程中调用的解析方法的名称。
  • printMethod 是在组合过程中调用的打印方法的名称。

声明可用于:

  • 一个 声明
  • 用于简单类型定义、GlobalBindings 声明的注释元素
  • 一个 声明

请参见MyDatatypeConverter 类 ,了解在自定义数据类型转换器类中如何实现 声明和 DatatypeConverterInterface 接口的示例。

类型安全枚举绑定声明

类型安全枚举声明提供了一种将 XML simpleType 元素映射到 Java typesafe enum 类的本地化方式。您可以进行两种类型的类型安全枚举声明:

  • 允许您将整个 simpleType 类映射到 typesafe enum 类。
  • 允许您将 simpleType 类的选定成员映射到 typesafe enum 类。

在这两种情况下,对此类型的自定义有两个主要限制:

  • 只有具有枚举约束的 simpleType 定义才能使用此绑定声明进行自定义。
  • 此自定义仅适用于一次仅有一个 simpleType 定义。要在全局级别映射一组相似的 simpleType 定义,请在 声明中使用 typesafeEnumBase 属性,如全局绑定声明中所述。

自定义的语法为:

<typesafeEnumClass 
    [ name = "enumClassName" ]
    [ <typesafeEnumMember> ... </typesafeEnumMember> ]*
    [ <javadoc> enumClassJavadoc </javadoc> ]
</typesafeEnumClass>
  • name 必须是有效的 Java 标识符,并且不能有包前缀。
  • 您可以在声明中嵌入零个或多个声明。
  • 定制了枚举类的 Javadoc 工具注释。

定制的语法是:

<typesafeEnumMember 
    name = "enumMemberName">
    [ value = "enumMemberValue" ]
    [ <javadoc> enumMemberJavadoc </javadoc> ]
</typesafeEnumMember>
  • name必须始终指定,并且必须是有效的 Java 标识符。
  • value必须是源模式中指定的枚举值。
  • 定制了枚举常量的 Javadoc 工具注释。

对于内联注释,必须在元素的注释元素中指定声明。必须在枚举成员的注释元素中指定。这使得枚举成员可以独立于枚举类进行定制。

有关类型安全枚举设计模式的信息,请参阅Joshua Bloch 的Effective Java Programming在 Oracle Technology Network 上的示例章节。

javadoc 绑定声明

声明允许您向基于模式的 JAXB 包、类、接口、方法和字段添加自定义 Javadoc 工具注释。请注意,声明不能全局应用;它们只能作为其他绑定定制的子元素有效。

定制的语法是:

<javadoc>
    Contents in <b>Javadoc<\b> format.
</javadoc>

<javadoc>
    <<![CDATA[Contents in <b>Javadoc<\b> format ]]>
</javadoc>

请注意,应用于包级别的声明中的文档字符串必须包含开放和关闭标签;例如:

<jxb:package 
    name="primer.myPo">
    <jxb:javadoc>
        <![CDATA[<body>
            Package level documentation for generated package primer.myPo.
        </body>]]>
    </jxb:javadoc>
</jxb:package>

定制命名空间前缀

所有标准的 JAXB 绑定声明必须以映射到 JAXB 命名空间 URI java.sun.com/xml/ns/jaxb 的命名空间前缀为前缀。例如,在此示例中,使用了jxb:。为此,您想要使用标准 JAXB 绑定声明自定义的任何模式必须在模式文件的顶部包含 JAXB 命名空间声明和 JAXB 版本号。例如,在 Customize Inline 示例的po.xsd中,命名空间声明如下:

<xsd:schema 
    xmlns:xsd= "http://www.w3.org/2001/XMLSchema"
    xmlns:jxb= "http://java.sun.com/xml/ns/jaxb"
    jxb:version="1.0">

具有jxb命名空间前缀的绑定声明采用以下形式:

<xsd:annotation>
    <xsd:appinfo>
    <jxb:globalBindings 
        *binding declarations* />
    <jxb:schemaBindings>
        ...
        *binding declarations*         .
        ...
    </jxb:schemaBindings>
    </xsd:appinfo>
</xsd:annotation>

请注意,在此示例中,globalBindingsschemaBindings声明用于分别指定全局范围和模式范围的定制。这些定制范围在范围、继承和优先级中有更详细的描述。

内联定制示例

Customize Inline 示例演示了通过内联注释对名为po.xsd的 XML 模式进行的一些基本定制。此外,该示例实现了一个自定义数据类型转换器类MyDatatypeConverter.java,展示了处理自定义数据类型转换的定制中的打印和解析方法。

总结这个示例:

  1. po.xsd是一个包含内联绑定定制的 XML 模式。
  2. MyDatatypeConverter.java 是一个 Java 类文件,实现了 po.xsd 自定义中指定的打印和解析方法。
  3. Main.java 是自定义内联示例中的主要类文件,使用了由 JAXB 编译器生成的模式派生类。

使用 Ant 构建和运行自定义内联示例

要使用 Ant 编译和运行自定义内联示例,在终端窗口中,转到 jaxb-ri-install/samples/inline-customize/ 目录并输入以下内容:

ant 

此示例中的关键自定义和自定义的 MyDatatypeConverter.java 类在下一节中有更详细的描述。

自定义模式

在自定义内联示例中使用的自定义模式位于文件 jaxb-ri-install/samples/inline-customize/po.xsd 中。自定义内容位于 标签中。

全局绑定声明

以下代码示例显示了 po.xsd 中的 globalBindings 声明:

<jxb:globalBindings
    fixedAttributeAsConstantProperty="true"
    collectionType="java.util.Vector"
    typesafeEnumBase="xsd:NCName"
    choiceContentProperty="false"
    typesafeEnumMemberName="generateError"
    bindingStyle="elementBinding"
    enableFailFastCheck="false"
    generateIsSetMethod="false"
    underscoreBinding="asCharInWord"/>

在此示例中,除了 collectionType 外,所有值都设置为默认值。

  • fixedAttributeAsConstantProperty 设置为 true 表示所有固定属性应绑定到 Java 常量。默认情况下,固定属性映射到更合适的简单属性或集合属性。
  • collectionType 设置为 java.util.Vector 指定生成实现类中所有列表在内部表示为向量。请注意,您为 collectionType 指定的类名必须实现 java.util.List 并且可以通过 newInstance 调用。
  • 如果将 typesafeEnumBase 设置为 xsd:string,这是一种全局方式,指定所有直接或间接从 xsd:string 派生并具有枚举约束的 simple 类型定义默认绑定到 typesafe enum。如果将 typesafeEnumBase 设置为空字符串 (""),则不会将任何 simple 类型定义默认绑定到 typesafe enum 类。typesafeEnumBase 的值可以是除 xsd:boolean 和两种二进制类型之外的任何原子简单类型定义。
  • JAXB 实现不支持 enableFailFastCheck 属性。

  • 注意: 使用类型安全的枚举类使您能够将模式枚举值映射到 Java 常量,这样就可以对 Java 常量进行比较,而不是对字符串值进行比较。

模式绑定声明

以下代码显示了 po.xsd 中的模式绑定声明:

<jxb:schemaBindings>
<jxb:package name="primer.myPo">
    <jxb:javadoc>
        <![CDATA[<body>
            Package level documentation for generated package primer.myPo.
        </body>]]>
    </jxb:javadoc>
</jxb:package>
    <jxb:nameXmlTransform>
        <jxb:elementName suffix="Element"/>
    </jxb:nameXmlTransform>
</jxb:schemaBindings>
  • 指定 primer.myPo 作为生成模式派生类的包。
  • 指定所有生成的 Java 元素接口默认附加Element到生成的名称。例如,当针对此模式运行 JAXB 编译器时,将生成元素接口CommentElementPurchaseOrderElement。相比之下,没有此自定义, 默认绑定会生成CommentPurchaseOrder。如果模式在不同的符号空间中使用相同的名称,例如在全局元素和类型定义中,此自定义可帮助您解决冲突,而不必使用单独的绑定声明逐个解决每个冲突。
  • 指定了primer.myPo包的自定义 Javadoc 工具注释。请注意,与在类级别显示的声明不同,当在包级别进行声明时,必须包含开头和结尾的标签。

类绑定声明

以下代码显示了po.xsd中的类绑定声明:

<xsd:complexType name="PurchaseOrderType">
    <xsd:annotation>
        <xsd:appinfo>
            <jxb:class name="POType">
                <jxb:javadoc>
                    A &lt;b>Purchase Order&lt;/b>
                    consists of addresses and items.
                </jxb:javadoc>
            </jxb:class>
        </xsd:appinfo>
    </xsd:annotation>
    <!-- ... -->
</xsd:complexType>

为基于模式的POType类编写的 Javadoc 工具注释将包含描述"一个<b>采购订单</b>包括地址和商品。" 其中<用于转义 HTML 标签中的开括号。


注意: 当在complexType定义的appinfo元素中指定自定义时,如前面的示例所示,complexType定义将绑定到 Java 内容接口。


po.xsd中,另一个自定义在此类级别声明,但这次使用CDATA转义 HTML 字符串:

<xsd:annotation>
    <xsd:appinfo>
        <jxb:class>
            <jxb:javadoc>
                <![CDATA[
                    First line of documentation for a
                    <b>USAddress</b>.]]>
            </jxb:javadoc>
        </jxb:class>
    </xsd:appinfo>
</xsd:annotation>

注意: 如果要在自定义中包含 HTML 标签,必须将数据放在CDATA部分中或使用<转义所有左尖括号。有关更多信息,请参阅XML 1.0 第 2 版


属性绑定声明

这里特别感兴趣的是generateIsSetMethod自定义,它导致生成两个额外的属性方法,isSetQuantityunsetQuantity。这些方法使客户端应用程序能够区分模式默认值和在实例文档中明确出现的值。

例如,在po.xsd中:

<xsd:complexType name="Items">
    <xsd:sequence>
        <xsd:element name="item" 
            minOccurs="1"  
            maxOccurs="unbounded">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element 
                        name="productName" 
                        type="xsd:string"/>
                    <xsd:element 
                        name="quantity" 
                        default="10">
                        <xsd:annotation>
                            <xsd:appinfo>
                                <jxb:property 
                                    generateIsSetMethod="true"/>
                            </xsd:appinfo>
                        </xsd:annotation>
                        <!-- ... -->
                    </xsd:complexType>
            </xsd:element>
    </xsd:sequence>
</xsd:complexType>

@generateIsSetMethod适用于quantity元素,该元素绑定到Items.ItemType接口中的属性。在Items.ItemType接口中生成了unsetQuantityisSetQuantity方法。

MyDatatypeConverter

jaxb-ri-install/samples/inline-customize/src/inlinecustomize/primer/MyDatatypeConverter,如下例所示,提供了一种自定义将 XML 数据类型与 Java 数据类型之间的转换的方法,使用自定义。

package primer;
import java.math.BigInteger;
import javax.xml.bind.DatatypeConverter;
public class MyDatatypeConverter {
    public static short parseIntegerToShort(String value) {
        BigInteger result = DatatypeConverter.parseInteger(value);
        return (short)(result.intValue());
    }
    public static String printShortToInteger(short value) {
        BigInteger result = BigInteger.valueOf(value);
        return DatatypeConverter.printInteger(result);
    }
    public static int parseIntegerToInt(String value) {
        BigInteger result = DatatypeConverter.parseInteger(value);
        return result.intValue();
    }
    public static String printIntToInteger(int value) {
        BigInteger result = BigInteger.valueOf(value);
        return DatatypeConverter.printInteger(result);
    }
};

以下代码显示了如何在 po.xsd 中的 声明中引用 MyDatatypeConverter 类:

<xsd:simpleType name="ZipCodeType">
<xsd:annotation>
    <xsd:appinfo>
    <jxb:javaType name="int"
        parseMethod="primer.MyDatatypeConverter.parseIntegerToInt"
        printMethod="primer.MyDatatypeConverter.printIntTo Integer" />
    </xsd:appinfo>
</xsd:annotation>
    <xsd:restriction base="xsd:integer">
    <xsd:minInclusive value="10000"/>
    <xsd:maxInclusive value="99999"/>
    </xsd:restriction>
</xsd:simpleType>

在此示例中,jxb:javaType 绑定声明覆盖了此类型的默认 JAXB 绑定为 java.math.BigInteger。对于 Customize Inline 示例,ZipCodeType 的限制(特别是有效的美国邮政编码限于五位数字)使得所有有效值都可以适应 Java 基本数据类型 int。还要注意,因为 ZipCodeType 中声明,所以该定制适用于所有引用此 simpleType 定义的 JAXB 属性,包括 getZipsetZip 方法。

DataType Converter 示例

DataType Converter 示例类似于 Customize Inline 示例。与 Customize Inline 示例一样,DataType Converter 示例中的定制是通过在应用程序的 XML 模式 po.xsd 中使用内联绑定声明来实现的。

Customize Inline 和 DataType Converter 示例的全局、模式和包以及大多数类自定义是相同的。DataType Converter 示例与 Customize Inline 示例不同之处在于用于将 XML 数据转换为 Java int 数据类型的 parseMethodprintMethod

具体而言,DataType Converter 示例不是使用自定义的 MyDataTypeConverter 类中的方法执行这些数据类型转换,而是使用 javax.xml.bind.DatatypeConverter 提供的内置方法:

<xsd:simpleType name="ZipCodeType">
    <xsd:annotation>
        <xsd:appinfo>
            <jxb:javaType 
                name="int"
                parseMethod="javax.xml.bind.DatatypeConverter.parseInt"
                printMethod="javax.xml.bind.DatatypeConverter.printInt"/>
        </xsd:appinfo>
    </xsd:annotation>
    <xsd:restriction base="xsd:integer">
        <xsd:minInclusive value="10000"/>
        <xsd:maxInclusive value="99999"/>
    </xsd:restriction>
</xsd:simpleType>

使用 Ant 构建和运行 DataType Converter 示例

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

ant
绑定声明文件

以下各节提供有关绑定声明文件的信息:

  • JAXB 版本、命名空间和模式属性
  • 全局和模式绑定声明
  • 类声明

JAXB 版本、命名空间和模式属性

所有 JAXB 绑定声明文件必须以以下内容开头:

  • JAXB 版本号
  • 命名空间声明
  • 模式名称和节点

bindings.xjb 中的版本、命名空间和模式声明如下:

<jxb:bindings 
    version="1.0"
    >
    <jxb:bindings 
        schemaLocation="po.xsd" 
        node="/xs:schema">
            <!-- ...
            *binding-declarations* 
            ... -->
    </jxb:bindings>
    <!-- 
    schemaLocation="po.xsd" 
    node="/xs:schema" -->
</jxb:bindings>

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

相关文章
|
1月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
3月前
|
Java 开发者 UED
【实战宝典】Java异常处理大师级教程:throws关键字,让异常声明成为你的专属标签!
【实战宝典】Java异常处理大师级教程:throws关键字,让异常声明成为你的专属标签!
60 3
|
20天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
20天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
20天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
|
6天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
10 0
|
29天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
70 2
|
1月前
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
|
1月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
本系列教程笔记详细讲解了Kotlin语法,适合希望深入了解Kotlin的开发者。对于需要快速学习Kotlin的小伙伴,推荐查看“简洁”系列教程。本篇笔记重点介绍了Kotlin与Java混编的技巧,包括代码转换、类调用、ProGuard问题、Android库开发建议以及相互调用时的注意事项。
24 3
|
1月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
22 3
下一篇
无影云桌面