Jaxb 绑定学习探索(二.进阶篇)
- 简介
- 自定义jaxb绑定
简介
上一篇文章我们已经介绍了如何使用maven 插件把xsd转化为java bean,而这篇文章主要是简析jaxb bindings中的内容。是对于oracle官网的使用手册的翻译解析。
自定义jaxb绑定
本节刚开始讨论您可以对JAXB绑定和验证方法进行自定义的表面。有关更多信息,请参阅JAXB规范(http://java.sun.com/xml/downloads/jaxb.html)。 绑定的两种方式:
随着注释在xml模式中内联
作为传递给JAXB绑定编译器的外部文件中的语句
为什么要自定义?
在大多数情况下,JAXB绑定编译器生成的默认绑定足以满足您的需求。但是,有些情况下您可能需要修改默认绑定。其中一些包括:
为新的jaxb包,类,方法和常量,添加注释创建API文档,解释您实现的概念,准则和规则。(即注释功能)
为默认的XML转化为java过程中无法自动处理的情况做出修正,例如:
解决名称冲突,多个变量的名称相同,无法区分哪个变量是属于哪个类,注意,JAXB绑定编译器会检测并报告所有名称冲突。(解决冲突)
提供非合法Java标识符的类型安全枚举常量的名称; 例如,枚举整数值。 (新建新类型)
为未命名模型组的Java表示绑定到Java属性或类时提供更好的名称(即可以根据自己的需求更改属性和类的名称)
提供比目标名称空间URI默认派生的更有意义的软件包名称(可以决定生成的java bean所属的包名)
覆盖默认绑定,例如:
指定模型组应该绑定到类而不是列表
指定可以将固定属性绑定到Java常量
将XML Schema内置数据类型的指定默认绑定覆盖为Java数据类型。在某些情况下,您可能需要引入一个替代Java类,它可以表示内置XML Schema数据类型的其他特征。本节介绍一些核心JAXB定制概念:
内联和外部自定义
1.内联,写在要转换的xml里。
2.外部绑定,写在外部文件中,使用配置文件定义绑定位置。
优缺点:使用内联自定义更加容易,因为您可以在所应用的模式的上下文中看到自定义。使用外部绑定自定义文件,您可以自定义JAXB绑定而无需修改源架构,并且使您可以轻松地将自定义项一次应用于多个架构文件。
注意:您可以合并这两种自定义 - 例如,您可以在内联注释中包含对外部绑定自定义文件的引用 - 但无法在同一模式元素上声明内联和外部自定义。内联自定义
内联自定义配置:<xs:annotation> <xs:appinfo> . jaxb binding tags here (jaxb:globalBindings, jaxb:bindings . </xs:appinfo> </xs:annotation>
例如:
<xs:annotation> <xs:appinfo> <jaxb:schemaBindings > <jaxb:package name="com.example.sandbox.internal.xsd.store"/> </jaxb:schemaBindings> </xs:appinfo> </xs:annotation>
- 外部自定义
<jxb:bindings schemaLocation = "xs:anyURI">
<jxb:bindings node = "xs:string">*
<binding declaration>
<jxb:bindings>
</jxb:bindings>
schemaLocation 是xml文件的位置,可以是本地相对路径,也可以是网页地址。
node是一个XPath 1.0表达式,用于标识schemaLocation给定绑定声明关联的模式节点。
例如,JAXB绑定声明文件中的第一个schemaLocation/ node声明指定了模式名称和根模式节点:
<jxb:bindings schemaLocation =“po.xsd”node =“/ xs:schema”>
后面的schemaLocation/node声明,比如上述模式中simpleType命名的元素ZipCodeType,将采用以下形式:
<jxb:bindings node =“// xs:simpleType [@ name ='ZipCodeType']”>
绑定自定义文件应该是直接的ASCII文本。名字或扩展名无关紧要,本章使用的是一个典型的扩展名.xjb
- 外部绑定自定义的限制
必须以属性开头,加上jaxb和xmlSchema命名空间的属性:
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
定制语法
- 全局绑定声明
全局定义:定义全局所有相应内容都改变
例如,Serializable类都按如下方式生成:
<jxb:globalBindings>
<jxb:serializable uid="1" />
</jxb:globalBindings>
全局范围自定义使用。全局范围自定义的语法如下所示:
<globalBindings>
[ collectionType = "collectionType" ]
//定义集合类的类型为""
[ fixedAttributeAsConstantProperty = "true" | "false" | "1" | "0" ]
//固定属性为常量属性
[ generateIsSetMethod = "true" | "false" | "1" | "0" ]
//是否生成isset()的方法
[ enableFailFastCheck = "true" | "false" | "1" | "0" ]
//启用失败快速检查
[ choiceContentProperty = "true" | "false" | "1" | "0" ]
//暂时还不明白什么属性
[ underscoreBinding = "asWordSeparator" | "asCharInWord" ]
//单词分隔或则是字符分隔
[ typesafeEnumBase = "typesafeEnumBase" ]
[ typesafeEnumMemberName = "generateName" | "generateError" ]
//枚举类型设置,详见枚举绑定声明
[ enableJavaNamingConventions = "true" | "false" | "1" | "0" ]
//启用Java命名约定
[ bindingStyle = "elementBinding" | "modelGroupBinding" ]
// 绑定类型,暂时不清楚有什么区别
[ <javaType> ... </javaType> ]*
// java类的绑定说明
</globalBindings>
声明仅在annotation顶层元素的元素中有效schema。任何给定的模式或绑定声明文件中只能有一个声明的单个实例。如果一个源模式包含或导入第二个源模式,则该声明必须在第一个源模式中声明。
- 模式绑定声明
架构范围自定义是使用声明。模式范围自定义的语法是:
<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>
类名前后缀修改实例
如上所示,‘schemaBinding’声明包含两个子组件:
package 指定包的名称,并且如果需要,指定模式派生类的API文档的位置。
nameXmlTransform 指定要应用的自定义。
类绑定声明
<class [ name = "className"] [ implClass= "implClass" ] > [ <javadoc> ... </javadoc> ] </class>
该
<class>
绑定声明可以自定义模式元素结合到Java内容接口或Java Element接口。<class>
声明可以用来定制:模式派生的Java接口的名称
模式派生的Java内容接口的实现类。- name是派生的Java接口的名称。它必须是合法的Java接口名称,并且不能包含包前缀。包前缀从包的当前值继承。
- implClass是实现类的名称,className并且必须包含完整的包名称。
- 该元素指定模式派生Java接口的Javadoc工具注释。此处输入的字符串必须使用CDATA或<转义嵌入的HTML标记
class 绑定是可以定义接口及其实现类的绑定声明。
例如:
<jxb:bindings schemaLocation="nmap.xsd">
<jxb:bindings node="//xsd:element[@name='scaninfo']">
<jxb:class name="MyBook" implClass="MyBook"/>
</jxb:bindings>
没有类绑定声明时,生成类名:ScanInfo,绑定后生成类为MyBook
属性绑定声明
该绑定声明可以自定义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标识符。属性的名字 比如Address ad;修改name=”addr”,则生成java bean 变为Address addr(解决冲突的方法之一)
- collectionType定义属性的的集合类型,此种绑定会出现无法转化的结果,一定要理解xsd文件所定义的属性类型才可修改。
- fixedAttributeAsConstantProperty固定属性为常量属性,该属性需要设置时使用方可,见全局定义声明。
- generateIsSetMethod,是否生成isset()方法。
- enableFailFastCheck 开启失败快速检查。
<javadoc>
为属性的getter方法定制javadoc工具注释。
<javaType>
绑定声明
当默认JAXB绑定不能充分代表你想要的类时,该声明允许自定义数据类型绑定。
目标Java数据类型可以是Java内置数据类型或特定于应用程序的Java数据类型。如果使用特定于应用程序的数据类型作为目标,则您的实现还必须提供解析和打印方法,用于解组和编组数据。为此,JAXB规范支持a parseMethod和printMethod:- 在parseMethod解组为一个字符串从输入文档转换为目标Java数据类型的值时被调用。
- 所述printMethod编组到所述目标类型的值转换成一个词汇表示期间被调用。
定制语法为:
<javaType name =“ javaType”
[xmlType =“ xmlType”]
[hasNsContext =“true”| “false”]
[parseMethod =“ parseMethod”]
[printMethod =“ printMethod”]>
该绑定,即是修改element的javaType ,如果生成的是新的javaType,通常标签为:<xs:complexType>
,javaType即是修改了javaType的属性。- name是xmlType要绑定到的Java数据类型。
- xmlType是javaType要绑定到的XML模式数据类型的名称; 这个属性在
<javaType>
声明的父项是必需的时候是必需的<globalBindings>
。 - parseMethod 是解组过程中要调用的解析方法的名称。
- printMethod 是编组过程中要调用的打印方法的名称。
- hasNsContext允许将命名空间上下文指定为打印或分析方法的第二个参数; 可以是true,false,1,或0。默认情况下,这个属性是false,并且在大多数情况下你不需要改变它。
该声明可用于:
一个声明
简单类型定义的注释元素GlobalBindings,和声明。
一个声明。