http://www./course/3_program/java/javajs/200853/112204.html
本文是对Java Web Service Development Pack 2.0中JAXB部分的翻译,如有转载,请声明!
Java Architecture for XML Binding README Specification Version:2.0 Reference Implementation(RI) Version:2.0 ea3 JAXB提供了自动映射XML文档和Java对象的API和工具。 JAXB框架可以完成下面的操作: ® 将XML内容Unmarshal成Java表示 ® 访问和更新Java表示 ® 将XML内容的Java表示Marshal成XML内容 JAXB提供了XML和Java代码之间的高效并且标准的映射。Java开发人员可以使用JAXB来简化开发,提高效率,因为使用JAXB可以写很少的代码,并且不需要很精通XML。JAXB使得开发人员可以很容易的使用XML和Web Service技术来扩展应用程序。 1. Release Notes JAXB Reference Implementation需要运行在J2SE 5.0或者更高的Java平台上。需要的JAR文件如下: 2.0运行环境:为Deploy JAXB2.0客户端所需要的JAR文件包括jaxb-api.jar,jaxb-impl.jar,jsr173-1.0_api.jar 1.0运行环境:为Deploy JAXB1.0客户端所需要的JAR文件包括2.0运行环境+jaxb1-impl.jar 2. XJC工具 虽然在笔者的其他文章中,包含了关于XJC脚本文件的使用,但是为了保持文章的完整性,将XJC脚本的内容再次追加在本文中。 绑定schema表示生成一系列的Java类,这些java类表示了schema。所有的JAXB实现都提供了一个工具叫做绑定编译器来将一个schema绑定。例如,JAXB参考实现提供了一个绑定编译器,允许通过脚本来执行(shell/bat)。假设需要将books.xsd文件进行绑定,并且假设是工作与*nix系统,那么绑定的命令如下: xjc.sh -p test.jaxb books.xsd -d work 选项说明: -p:指定生成的类的包名 -d:指定存放类的目标目录 (译者注:其实绑定schema还有其他的选项和方法,例如Eclispe的xjc插件等) C:\Documents and Settings\hp3643>xjc --help Usage: xjc [-options ...] <schema file/URL/dir> ... [-b <bindinfo>] ... Options: -nv : 不进行输入schema的严格检查,默认情况下,XJC会进行严格的Schema检查,使用这个选项可以不进行严格的Schema检查,只是进行不太严格的检查 -extension : 默认情况下,XJC绑定编译器强制执行JAXB规范中的兼容性部分的规则,Appendix E.2定义了一些列JAXB v1.0所不支持的W3C XML Schema特性。这时,就可以使用-extension模式来支持这些特性。在默认情况下,只能使用规范中定义的绑定自定义。通过使用-extension选项,可以使用JAXB提供商扩展。 -b <file> : 指定外部绑定文件(每个<file>要有自己的-b,与出现顺序无关) 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 -d <dir> : 生成文件的目标路径,默认情况下在当前目录生成Java内容类,目标目录必须已经存在,XJC不会自动创建这些目录 -p <pkg> : 指定目标包名 -httpproxy <proxy> : 设置HTTP/HTTPS代理,格式为[user[:password]@]proxyHost[:proxyPort] -classpath <arg> : 指定用户的类路径 -catalog <file> : 指定范畴文件,用于处理外部实体应用 支持TR9401, XCatalog, and OASIS XML Catalog格式. -readOnly : 生成的文件的状态为只读 -npa : 不生成包级别的annotations -xmlschema : 将输入当作W3C XML Schema (默认)处理 -relaxng : 将输入当作RELAXNG (试验阶段,不支持)处理 -relaxng-compact : 将输入当作RELAXNG comapact语法 (试验阶段,不支持)处理 -dtd : 将输入当作XML DTD (experimental,unsupported) -wsdl : 将输入当作WSDL处理(experimental,unsupported) -verbose : 额外的显示 -quiet : 不输出编译结果 -help : 显示帮助信息 -version : 显示版本信息 Extensions: -Xlocator : 对生成的代码启用源代码位置支持 -Xsync-methods : 生成访问的方法标志为''synchronized''关键字 -mark-generated : 将生成的代码标记为@javax.annotation.Generated windows下运行命令: F:\eclipse\workspace\JAXBTutorial\src>xjc -p test.jaxb -d . text/jaxp/book.xsd (译者注:译者的系统中安装了Java(TM) Web Services Developer Pack 2.0,安装目录为C:\Sun\jwsdp-2.0,并将C:\Sun\jwsdp-2.0\jaxb\bin添加到了系统的path环境属性中) parsing a schema... compiling a schema... test\jaxb\BookCategoryType.java test\jaxb\BookType.java test\jaxb\Collection.java test\jaxb\ObjectFactory.java 运行完上述命令后,会生成一些类。 3. XJC Ant Task 在jwsdp或者其他的jaxb ri库中,都包含了jaxb-xjc.jar这个文件,在这个文件中,包含了XJCTask.class文件,这个文件可以应用于Ant构建工具中。在Ant构建脚本(一般为build.xml)中包含如下的语句: <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask"> <classpath> <fileset dir="path/to/jaxb/lib" includes="*.jar" /> </classpath> </taskdef> 上面的task定义将XJCTask映射到Ant task,并命名为xjc。在样例程序中包含了如何使用xjc任务。 该任务的语法如下: 环境变量: ANT OPTS –将命令行参数传递给JVM。例如定义系统属性或者设置最大的Java堆大小。 参数属性: xjc支持以下的参数属性: schema:xml schema文件。这个属性或者<schema>子元素必须包含一个。 binding:外部绑定文件,应用于schema文件。 package:如果指定了的话,那么生成的java文件会放在这个包下,与命令行参数-p一样。 destdir:目标目录,与命令行参数-d一样。必须属性。 readonly:是否以只读方式生成java源文件,默认为false。 extension:如果设置为true,那么XJC绑定表一起会以扩展方式运行,否则的话,会按照严格的方式运行。和命令行工具的-extension参数一样。 catalog:指定分类文件来处理外部实体引用。 removeOldOutput:和<produces>子元素承兑使用。当设置为yes时,由<produces>元素指向的文件会在运行XJC编译器之前删除。 source:指定使用哪个版本的编译器。可以是1.0或者2.0.生成的Java代码会参考JAXB1.0或者JAXB2.0规范制定的规则。 xjc支持下面的嵌套元素: schema:同时编译一个或者多个schema,schema子元素的语法和<fileset>相同。 binding:可以同时指定一个或者多个外部绑定文件,binding子元素的语法和<fileset>相同。 classpath:指定由用户指定的类路径。 arg:一些额外的命令行参数。这个元素可以指定多个选项: -nv -use-runtime -schema -dtd -relaxng -Xlocator -Xsync-methods 下面是一些使用XJC Task的例子: 编译src/myschema.xmd,目标目录为src,包名为org.acme.foo: <xjc schema="src/myschema.xsd" target="src" package="org.acme.foo"/> 编译src下面的所有schema文件,目标目录为src,包名默认: <xjc target="src"> <schema dir="src" includes="*.xsd"/> </xjc> 编译src下面的所有schema文件,目标目录为src,绑定为src目录下的所有xjb文件: <xjc target="src"> <schema dir="src" includes="*.xsd"/> <binding dir="src" includes="*.xjb"/> </xjc> 由于ant默认需要fileset中的文件夹必须存在,所以mkdir是必须的,下面的例子做了一个up-to-date的检查,如果abc.xsd有更新的话,那么src/org/acme/foo和其impl子目录的文件在编译之前就会被删除,所以不要将自己编写的类文件放在上述两个目录中。 <mkdir dir="src/org/acme/foo" /> <xjc target="src" schema="abc.xsd" removeOldOutput="yes" package="org.acme.foo"> <produces dir="src/org/acme/foo" includes="* impl/*" /> </xjc> 更加复杂的up-to-date检查,如果xsd进行了更新,或者dtd文件进行了更新,都需要进行重新的编译schema。 <mkdir dir="src/org/acme/foo" /> <xjc target="src" removeOldOutput="yes" package="org.acme.foo"> <schema dir="schema" includes="*.xsd" /> <depends dir="schema" includes="*.dtd" /> <produces dir="build/generated-src/org/acme/foo" includes="**/*" /> </xjc> 使用arg子元素: <xjc target="src"> <schema dir="src" includes="**/*.xsd" excludes="**/debug.xsd"/> <arg value="-nv" /> </xjc> 设置环境变量或者系统属性: > set ANT_OPTS=-Dhttp.proxyHost=webcache.east > set ANT_OPTS=%ANT_OPTS% -Dhttp.proxyPort=8080 > ant 4. SchemaGen工具 schema生成器可以通过schemagen shell脚本或者bat批处理文件来运行。目前schema生成器可以处理java源文件或者class文件。 同时,也提供了Ant task的方式来运行Schema生成器。 对于不同的操作系统,使用这个工具的例子如下: For Solaris/Linux % path/to/jaxb/bin/schemagen.sh Foo.java Bar.java ... For WindowsNT/2000/XP > path\to\jaxb\bin\schemagen.bat Foo.java Bar.java ... 注意:默认的schema文件的文件名为schema1.xsd。 如果Java源文件或者类文件需要参考其他的类,那么必须可以通过系统的CLASSPATH来访问,或者需要指定-classpath选项,否则的话,会发生错误。 命令行参数: Usage: schemagen [options ...] <java files> Options: -d <path> :指定将处理器和javac生成的类文件放在哪个目录中 -cp <path> :用户指定文件的目录 -classpath <path> :用户指定文件的目录 -help :显示帮助信息 目前schema生成器为Java类文件使用的名称空间生成schema文件。没有办法控制生成的schema文件的名字,可以使用Ant任务来完成这个功能。 5. Schema生成器的Ant Task jaxb-xjc.jar文件中包含了SchemaGenTask.class文件,这样就可以在Ant构建工具中使用schema生成器了。SchemaGenTask的定义如下: <taskdef name="schemagen" classname="com.sun.tools.jxc.SchemaGenTask"> <classpath> <fileset dir="path/to/jaxb/lib" includes="*.jar" /> </classpath> </taskdef> 参数属性:
schemagen支持javac定义的大多数属性。并且支持下面的参数属性: destdir:生成的schema文件的基准目录。 classpath:和子元素<classpath>功能相同。 schemagen支持所有的javac任务定义的子元素。 schema:控制生成的schema文件的名字。这个元素必须设置namespace属性和file属性。当这个元素存在的时候,指定的namespace的schema文件的名字和file属性指定的名字相同。文件名和destdir属性指定的文件名是相对的。当不存在destdir时,将项目basedir作为destdir。可以多次设置schema元素。 classpath:和路径类似的结构来表示classpath。 下面是一些schemagen生成器的例子: 将src目录下的源文件生成schema文件,保存在build/schemas目录。 <schemagen srcdir="src" destdir="build/schemas"> 使用javac的子元素: <schemagen destdir="build/schemas"> <src path="src" /> <exclude name="Main.java"/> </schemagen> 6. JAXB RI Extensions 运行时属性: JAXB RI提供了一些在JAXB规范中没有定义的额外的Marshaller属性,这些属性可以更好的控制marshalling过程。但是,这只适用于JAXB RI,不一定适用于其他的JAXB提供者。 名称前缀映射 属性名:com.sun.xml.bind.namespacePrefixMapper 类型:com.sun.xml.bind.marshaller.NamespacePrefixMapper 默认值:无 JAXB RI提供了一个方法来将URI名称空间映射到前缀。下面是通常的过程: 应用程序开发人员提供一个com.sun.xml.bind.marshaller.NamespacePrefixMapper的实现 接着将这个类设置为RI指定的com.sun.xml.bind.namespacePrefixMapper属性 每当marshaller遇到一个URI,都会回调映射 当mapper返回值时,marshaller就会使用这个值 com.sun.xml.bind.marshaller.NamespacePrefixMapper类需要实现下面的方法: public abstract class NamespacePrefixMapper { /** * Returns a preferred prefix for the given namespace URI. * * This method is intended to be overrided by a derived class. * * @param namespaceUri * The namespace URI for which the prefix needs to be found. * Never be null. "" is used to denote the default namespace. * @param suggestion * When the content tree has a suggestion for the prefix * to the given namespaceUri, that suggestion is passed as a * parameter. Typically this value comes from QName.getPrefix() * to show the preference of the content tree. This parameter * may be null, and this parameter may represent an already * occupied prefix. * @param requirePrefix * If this method is expected to return non-empty prefix. * When this flag is true, it means that the given namespace URI * cannot be set as the default namespace. * * @return * null if there''s no preferred prefix for the namespace URI. * In this case, the system will generate a prefix for you. * * Otherwise the system will try to use the returned prefix, * but generally there''s no guarantee if the prefix will be * actually used or not. * * return "" to map this namespace URI to the default namespace. * Again, there''s no guarantee that this preference will be * honored. * * If this method returns "" when requirePrefix=true, the return * value will be ignored and the system will generate one. */ public abstract String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix); } 如果这个属性被设置为null的话,下面默认的属性就会返回: public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { return suggestion; } 缩进 属性名:com.sun.xml.bind.indentString 类型:java.lang.String 默认值:” ”四个空格 这个属性用来控制XML的缩进。 注意需要设置jaxb.formatted.output属性来启用缩进。 转义字符 属性名:com.sun.xml.bind.characterEscapeHandler 类型:com.sun.xml.bind.marshaller.CharacterEscapeHandler 默认值:null 默认情况下,JAXB RI的实现会试着转义字符,这样的话,就可以安全的表示输出编码。 不过,由于各种技术原因,默认的操作可能不会满足要求。如果需要处理更敏捷的处理转义,那么可以按照如下过程进行操作: 实现com.sun.xml.bind.marshaller.CharacterEscapeHandler接口 创建创建一个实例 将实例设置为marshaller的属性 默认情况下的转义是和J2SE SDK的版本相关,如果运行J2SE SDK 版本1.3或者之前的版本不能满足转义需求的话,可以使用版本1.4或者之后的版本。 XML声明控制 属性名:com.sun.xml.bind.xmlDeclaration 类型:java.lang.Boolean 默认值:Boolean.TRUE 这是JAXB RI 1.0.x的实验属性,并且被JAXB 2.0标准所采用。2.0 RI会继续支持这个属性,但是客户端的代码应该使用Marshaller.JAXB_FRAGMENT属性。 在JAXB 2.0中,调用: marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE); 和调用 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 是等价的。 启用片段marshalling可以使得将一个片段输出到另外一个XML的时候。同样,当需要输出类似DOCTYPE声明或者XML样式表处理指示,参考如下的代码: PrintWriter out = ...; // print out the prolog part by ourselves out.println("<xml version=''1.0''?>"); out.println("<!DOCTYPE foo SYSTEM ''dummy.dtd''>"); marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE); marshaller.marshal( jaxbObject, out ); JAXB RI提供了JAXB规范没有定义的自定义内容。 这些特性只有在-extension模式下运行绑定编译器时才可以使用 所有JAXB RI供应商扩展都定义在http://java./xml/ns/jaxb/xjc名称空间 名称空间中包含了扩展绑定声明,这将使得全局属性@jaxb:extensionBindingPrefixes在<xs:schema>元素。这个属性的值是以空格分隔的名称空间前缀。 扩展普通的超类 <xjc:superClass>自定义属性可以指定一个full qualified name作为Java类名来作为所有的生成类的超类。<xjc:superClass>只可以在<jaxb:globalBindings>: <xs:schema xmlns:xs="http://www./2001/XMLSchema" xmlns:jaxb="http://java./xml/ns/jaxb" xmlns:xjc="http://java./xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc" jaxb:version="1.0"> <xs:annotation> <xs:appinfo> <jaxb:globalBindings> <xjc:superClass name="org.acme.RocketBooster"/> </jaxb:globalBindings> </xs:appinfo> </xs:annotation> . . . </xs:schema> 还可以扩展共同的接口 和扩展共同的类类似,只是使用<xjc:superInterface>来代替<xjc:superClass>。 <xs:schema xmlns:xs="http://www./2001/XMLSchema" xmlns:jaxb="http://java./xml/ns/jaxb" xmlns:xjc="http://java./xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc" jaxb:version="1.0"> <xs:annotation> <xs:appinfo> <jaxb:globalBindings generateValueClass="false"> <xjc:superInterface name="org.acme.RocketBooster"/> </jaxb:globalBindings> </xs:appinfo> </xs:annotation> . . . </xs:schema> 7. 关于Schema JAXB RI目前支持下面所列举的Schema语言。下面的一些特性并没有在JAXB规范中描述,只是在JAXB RI中才是可用的。 W3C Schema:JAXB 2.0 RI FCS会100%的支持W3C XML Schema。但是,现在的版本只是一个临时版本,还没有实现全部的功能。本节描述了JAXB 2.0规范。Section 8 描述了Java to XML,Section 6和7描述了XML to Java。 RELAX NG:目前还没有支持。 DTD:JAXB RI目前试着支持DTD,但是不能保证没有问题。可以使用下面的工具来编译XML的DTD。 $xjc.sh –dtd test.dtd |
|