SlideShare a Scribd company logo
Spring 作为 Java 应用程序框架,已在 Java 开发社区中得到广泛使用,SpringSource 近日发布了最新
版本 Spring 3.0.1 版本。文章主要针对 Spring 中的 Object/XML 映射,分析使用 Object/XML 映射的特性
与优势。


  Spring 以其流行的科技词汇而著名, “dependencyinjection 依赖项注入) 、
                      比如                  (       ”“inversionofcontrol
(控制反转)和
      ”“aspect-orientedprogramming 面向方面编程)等。
                                 (        ” 它还支持 Model-View-Controller(MVC)
模式,很好地兼容用于数据访问的各种数据库驱动程序。


  另外,它支持事务处理、单元测试、批处理和安全性。鉴于 Spring 的良好声誉和悠久历史,它通常是
应用程序快速开发的首选框架。但是,最大的好处也许是:Spring 是免费的。


  Object/XML 映射是什么?


  Spring 3.0 的一个新特性是 O/XMapper。O/X 映射器这个概念并不新鲜,O 代表 Object,X 代表 XML。它
的目的是在 Java 对象(几乎总是一个 plainoldJavaobject,或简写为 POJO)和 XML 文档之间来回转换。


  例如,您可能有一个带有几个属性的简单 bean,且您的业务需要将那个 Java 对象转换为一个 XML 文档。
Spring 的 O/XMapper 能够为您解决那个问题。如果反过来,您需要将一个 XML 文档转换为一个简单
Javabean,Spring 的 O/XMapper 也能胜任,有一点需要注意:SpringO/XMapper 只是定义由流行的第三方
框架实现的统一的界面。要利用 Spring 的 O/X 功能,您需要一个在 Java 对象和 XML 之间来回转换的实用
程序。Castor 就是这样一个流行的第三方工具,本文将使用这个工具。其他这样的工具包括 XMLBeans、
JavaArchitectureforXMLBinding(JAXB)、JiBX 和 XStream。


  编组和解组


  进行 O/X 映射时,您经常会看到编组(marshalling)和解组(unmarshalling)这两个术语。编组指将
Javabean 转换成 XML 文档的过程,这意味着 Javabean 的所有字段和字段值都将作为 XML 元素或属性填充
到 XML 文件中。有时,编组也称为序列化(serializing)。


  如您所料,解组是与编组完全相反的过程,即将 XML 文档转换为 Javabean,这意味着 XML 文档的所有元
素或属性都作为 Java 字段填充到 Javabean 中。有时,解组也称为反序列化(deserializing)。


  使用 Spring 的 O/XMapper 的好处


  使用 Spring 的 O/XMapper 的一个最直接的好处是可以通过利用 Spring 框架的其他特性简化配置。
                                                           Spring
的 bean 库支持将实例化的 O/X 编组器注入(即前面提到过的“依赖项注入”)使用那些编组器的对象。重
申一遍,这将加快应用程序开发和部署。


  遵循坚实的面向对象的设计实践,Spring Object/XML 框架只定义两个接口:Marshaller 和
Unmarshaller,它们用于执行 O/X 功能,这是使用这个框架的另一个重大好处。这些接口的实现完全对独
立开发人员开放,开发人员可以轻松切换它们而无需修改代码。例如,如果您一开始使用 Castor 进行 O/X
转换,但后来发现它缺乏您需要的某个功能,这时您可以切换到 XMLBeans 而无需任何代码更改。唯一需要
做的就是更改 Spring 配置文件以使用新的 Object/XML 框架。


  使用 Spring 的 Object/XML 映射的另一个好处是统一的异常层次结构。Spring 框架遵循使用它的数据访
问模块建立的模式,方法是将原始异常对象包装到 Spring 自身专为 O/XMapper 建立的运行时异常中。由于
第三方提供商抛出的原始异常被包装到 Spring 运行时异常中,您能够查明出现异常的根本原因。您也不必
费心修改代码以捕获异常,因为异常已包装到一个运行时异常中。以下几个运行时异常扩展了基础异常
XMLMappingException:GenericMarshallingFailureException、ValidationFailureException、
MarshallingFailureException 和 UnmarshallingFailureException。


  一个简单的演示


  现在您已经了解了 Spring 的 O/XMapper 的背景和基础知识,可以检验它的使用方法了。在本文中,您
首先创建一个简单的 Spring 应用程序,该程序独立于任何 JavaEnterprise 依赖项。然后,您创建一个简
单的 Java 类,它访问 Spring 的配置文件来实例化该类并注入 O/X 依赖项。参见下载部分获取所有源代码
文件(包括配置文件)的链接。


  编码


  首先应该注意 Spring 配置文件。清单 1 是应用程序用于执行编组和解组操作的配置文件。注意,这个
文件必须在运行时位于类路径中,清单 1.配置文件:


   1. <beansxmlnsbeansxmlns="http://www.springframework.org/schema/beans"
   2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   3. xsi:schemaLocation="http://www.springframework.org/schema/beans
   4. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
   5.
   6. <beanidbeanid="oxmExample"class="com.xyz.OXMExample">
   7. <propertynamepropertyname="marshaller"ref="castorMarshaller"/>
   8. <propertynamepropertyname="unmarshaller"ref="castorMarshaller"/>
   9. </bean>
   10. <beanidbeanid="castorMarshaller"class="org.springframework.oxm.castor.CastorMarshall
        er">
   11. <propertynamepropertyname="mappingLocation"value="classpath:mapping.xml"/>
   12. </bean>
   13. </beans>


  如您所见,这个配置文件只定义了两个 bean,这是为了简便起见。第一个 bean 是用于执行演示的类:
com.xyz.OXMExample。与该类关联的两个属性使用依赖项注入,它们都使用 castorMarshallerbean 的一个
实例注入。这是在 Spring 框架中定义 bean 的标准方法,经验丰富的 Spring 开发人员很快就会意识到这一
点。


  另一个 bean 是 castorMarshallerbean 本身,
                                    它是 org.springframework.oxm.castor.CastorMarshaller
的一个实例,org.springframework.oxm.castor.CastorMarshaller 主要用于包装 Castor 框架。如前所述,
使用 Spring 的 Object/XML 功能需要使用一个第三方 O/X 框架。在本例中,这个第三方产品是 Castor。还
要注意,有一个属性使用 castorMarshaller 定义,那是用于在 Javabean 和 XML 输出之间来回映射的映射
文件。这个文件称为 mapping.xml,它必须在运行时位于类路径中。我将稍后解释 mapping.xml 文件的内
容。清单 2 实际执行 O/X 映射器的代码的部分清单。它是一个简单的 Java 类,清单 2.OXMExample 类:


   1. publicclassOXMExample{
2. privatestaticfinalStringFILE_NAME="simplebean.xml";
3. privateSimpleBeansimpleBean;
4.
5. privateMarshallermarshaller;
6. privateUnmarshallerunmarshaller;
7.
8. publicvoidsetMarshaller(Marshallermarshaller){
9. this.marshaller=marshaller;
10. }
11.
12. publicvoidsetUnmarshaller(Unmarshallerunmarshaller){
13. this.unmarshaller=unmarshaller;
14. }
15.
16. publicvoidsaveSimpleBean()throwsIOException{
17. FileOutputStreamos=null;
18. try{
19. os=newFileOutputStream(FILE_NAME);
20. this.marshaller.marshal(simpleBean,newStreamResult(os));
21. }finally{
22. if(os!=null){
23. os.close();
24. }
25. }
26. }
27.
28. publicvoidloadSimpleBean()throwsIOException{
29. FileInputStreamis=null;
30. try{
31. is=newFileInputStream(FILE_NAME);
32. this.simpleBean
33. =(SimpleBean)this.unmarshaller.unmarshal(newStreamSource(is));
34. }finally{
35. if(is!=null){
36. is.close();
37. }
38. }
39. }
40.
41. publicstaticvoidmain(String[]args)throwsIOException{
42. ApplicationContextappContext
43. =newClassPathXmlApplicationContext("applicationContext.xml");
44. OXMExampleex=(OXMExample)appContext.getBean("oxmExample");
45. ex.go();
46. }
  47.
  48. privatevoidgo()throwsIOException{
  49. simpleBean=getSimpleBean();
  50.
  51. saveSimpleBean();
  52. loadSimpleBean();
  53.
  54. System.out.println("name:"+simpleBean.getName());
  55. System.out.println("jobdescription:"+simpleBean.getJobDescription());
  56. System.out.println("age:"+simpleBean.getAge());
  57. System.out.println("executive:"+simpleBean.isExecutive());
  58. }
  59.
  60.
  61. privateSimpleBeangetSimpleBean(){
  62. SimpleBeansimpleBean=newSimpleBean();
  63. simpleBean.setAge(35);
  64. simpleBean.setExecutive(false);
  65. simpleBean.setJobDescription("Janitor");
  66. simpleBean.setName("MisterJones");
  67.
  68. returnsimpleBean;
  69.
  70. }
  71. }


要解释清单 2,必须首先介绍 main 方法,因为该方法将先执行。然后再接着介绍清单 2,首先,在 main 方
法中,您的代码捕获 Spring 应用程序的上下文,就是您在清单 1 中看到的配置文件。这个文件必须在类路
径中,否则运行代码将产生一个异常。


 当您获得应用程序上下文时,OXMExample 的一个实例从该配置文件中提供的定义创建。注意,这个 bean
在代码中的名称(oxmExample)与配置文件中定义的名称(见清单 1)一致。创建 OXMExample 的一个实例
后,调用 go()方法。这有点反常,因为 Spring 框架实例化一个已经从命令行运行的对象,但那只是为了
实现演示目的而进行的简化。go()方法在打印结果数据前完成 3 个任务:


 1.创建 SimpleBean 的一个实例。


 2.编组该实例。


 3.解组从编组创建的 XML 文档。


 您使用 getSimpleBean()方法实例化一个包含一个虚拟员工的信息的 SimpleBean 对象。这个信息包含年
龄(一个整数)、工作描述(一个字符串)、姓名(一个字符串)和该员工是否是执行官(一个布尔型)。
您使用测试数据和返回调用者的返回对象(在本例中为 go()方法)填充字段。您在编组发生时将这个 bean
写入一个 XML 文件,在解组发生时读取那个 XML 文件的内容。


  saveSimpleBean()方法执行编组。首先,您获得一个指向 simplebean.xml 的对象,然后,您使用编组
器对象(通过 Spring 的依赖项注入实例化)调用 marshal 方法。这个方法需要两个参数:


  ◆要被编组的对象(本例中为 SimpleBean 实例)


  ◆一个 StreamResult 对象,它基本上表示一个 XML 输出抽象


  loadSimpleBean()方法执行解组。首先,您获取一个指向 simplebean.xml 的 FileInputStream 对象,
然后,您使用解组器对象(通过 Spring 的依赖项注入实例化)调用 unmarshal 方法。唯一需要的参数是一
个包装 FileInputStream 对象的 StreamSource 对象。注意,解组将创建一个泛型对象,因此您必须将其显
式设置为 SimpleBean 类型。


  即使这个类和 Spring 配置文件已经就绪,您也还没有准备好运行这段代码。还记得清单 1 中的映射文
件吗?您还需要定义那个映射文件。定义代码如清单 3 所示,而且,再说一遍,它也必须在运行时位于类
路径中。清单 3.mapping.xml 文件:


   1. <mapping>
   2. <classnameclassname="com.xyz.SimpleBean">
   3. <map-toxmlmap-toxml="simplebean"/>
   4. <fieldnamefieldname="age"type="integer">
   5. <bind-xmlnamebind-xmlname="age"node="element"/>
   6. </field>
   7. <fieldnamefieldname="executive"type="boolean">
   8. <bind-xmlnamebind-xmlname="is-executive"node="element"/>
   9. </field>
   10. <fieldnamefieldname="jobDescription"type="string">
   11. <bind-xmlnamebind-xmlname="job"node="element"/>
   12. </field>
   13. <fieldnamefieldname="name"type="string">
   14. <bind-xmlnamebind-xmlname="name"node="element"/>
   15. </field>
   16. </class>
   17. </mapping>


  清单 3 中的映射文件特定于 Object/XML 映射的 Castor 实现。第一个元素(class)定义要映射到一个
XML 输出的类。您必须指定完整路径,map-to 元素提供 XML 文件的根元素的名称。这很重要,因为 XML 规
范规定,每个 XML 文件必须有一个根元素。


  每个 field 元素都将被映射到 SimpleBean 类中的一个特定字段。每个 field 元素的 bind-xml 子元素用
于指定关于该字段的特定于 XML 的信息,如对应的 XML 元素的名称,每个字段的值应该是一个元素值还是
一个属性值。如您所见,在本例中,所有值都是元素值。
测试


 尽管代码已经编写完成,但在执行这个应用程序之前,您必须处理一些依赖项,特定于 Spring 的依赖
项有:


  1. org.springframework.asm-3.0.0.M4.jar
  2. org.springframework.beans-3.0.0.M4.jar
  3. org.springframework.context-3.0.0.M4.jar
  4. org.springframework.core-3.0.0.M4.jar
  5. org.springframework.expression-3.0.0.M4.jar
  6. org.springframework.oxm-3.0.0.M4.jar


 特定于 Castor 的依赖项有:


  1. castor-1.3-core.jar
  2. castor-1.3-xml.jar


 您还需要 commons-logging-1.1.1.jar 和 log4j-1.2.15.jar,因为 Spring 框架需要它们,所有这些
JavaArchive(JAR)文件必须在运行时位于类路径中。如果您在没有这些依赖项的情况下试图运行代码,您
很可能会收到一个异常,指出某个类没有找到。如果遇到这种情况,只需双击您的类路径,确保所有的必
要依赖项已就绪。事实上,要成功编译这段代码,您需要大部分 JAR 文件。


 您可以使用您钟爱的 IDE 或只是使用命令行来运行 OXMExample.class。要从命令行运行,只需从您的工
作目录输入 java-cp[classpath]OXMExample,这里的[classpath]是指向刚才提到的所有依赖项(JAR 文件
和配置文件)的类路径。首次运行该程序后,一个名为 simplebean.xml 的新文件将出现在您的工作目录中。
该文件的内容应该如清单 4 所示,清单 4.simplebean.xml 文件:


  1. <?xmlversionxmlversion="1.0"encoding="UTF-8"?>
  2. <simplebean>
  3. <age>35</age>
  4. <is-executive>false</is-executive>
  5. <job>Janitor</job>
  6. <name>MisterJones</name>
  7. </simplebean>


 清单 4 显示了来自应用程序的编组端的输出,而清单 5 则显示来自应用程序的解组端的结果,这些结果
将在您的控制台中显示,清单 5.解组输出:


  1. name:MisterJones
  2. jobdescription:Janitor
  3. age:35
  4. executive:false
现在,您已经成功地完成了您的首次 SpringO/X 映射测试,现在最好做开发人员应该做的工作:修改代
码。向类添加字段并将它们映射到 XML 文件。删除一些字段并将它们从 XML 文件中移除。参考 Castor 文档,
尝试一些更复杂的工作,比如嵌套元素。您可以随心所欲地尝试各种可能性。


  结束语


  Spring 的 O/X 映射接口是 Spring 框架的强大特性。借助它,您不仅可以将 XML 文档转换为 Java 对象,
还可以将 Java 对象转换为 XML 文档。它利用 Spring 的一个关键优势:依赖项注入。通过结合使用依赖项
注入和 Spring 的 O/XMapper,您可以轻松开发一个解决方案,该方案可以使用任一 O/X 实现,比如 Castor、
XBeans、JiBX、JAXB 和 XStream。由于各个特定实现是 Spring 强大的 InversionofControl 容器的一部分,
开发人员可以在多个特定 O/X 实现之间轻松切换而无需修改代码。


  Spring 的 O/XMapper 还向开发人员提供一个统一的异常层次结构,这意味着不管您使用哪个第三方实
现,抛出的运行时异常都是相同的。再强调一次,这将有利于在多个 O/X 供应商之间切换,在 Java 开发社
区中,提供 XML 支持的 Java 应用程序非常热门并且 Spring 框架被广泛使用,因此 Spring 的 O/XMapper 将
受到全世界 Java 应用程序开发人员的欢迎。

More Related Content

PDF
Spring 2.0 技術手冊第九章 - API 封裝
PDF
Spring 2.0 技術手冊第五章 - JDBC、交易支援
PDF
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
PDF
Spring 2.0 技術手冊第十章 - 專案:線上書籤
PDF
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架
PDF
Java并发核心编程
PPTX
并发控制
PDF
J2ee经典学习笔记
Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架
Java并发核心编程
并发控制
J2ee经典学习笔记

What's hot (10)

PDF
Oracle prm数据库恢复工具与asm
PDF
Spring 2.0 技術手冊第二章 - Spring 入門
PPT
AOP概念及实践
PPT
第9章 t sql程序设计
DOC
Java 面试32问
DOC
Java面试知识
PPT
Class Inheritance
PPTX
4, workflow tables & api
PDF
资身Dba经验谈
PDF
Hash map导致cpu100% 的分析
Oracle prm数据库恢复工具与asm
Spring 2.0 技術手冊第二章 - Spring 入門
AOP概念及实践
第9章 t sql程序设计
Java 面试32问
Java面试知识
Class Inheritance
4, workflow tables & api
资身Dba经验谈
Hash map导致cpu100% 的分析
Ad

Viewers also liked (19)

PDF
Biological Bases of Meditation and Yoga Therapy
PPTX
веселое путешествие
PDF
Do I Have Your Attention: Examining the Influence of Unconscious Memories on ...
PPTX
Mentoring101
PPTX
Exploring A Holistic Multicultural Approach to Problem Solving in Education P...
PDF
Biological Bases of Meditation and Yoga Therapy Supplemental Report
PPT
инфракрасное излучение
PPTX
Honors and Awards
DOC
Plan de afaceri ricop sme - 31 may
PDF
Arondare strazi cls1 2012 2013
DOCX
Ig5 brief 2 in salford and proud
PPT
презентация Microsoft power point
PPTX
Comparing Pharmacological VS Psychedelic Treatments for Anxiety Disorders
PDF
Re:Mark{able} Females: Sexual Pleasures, Risks and Rewards of Tattoos, Genita...
PDF
How Useful Are Sexual Recidivism Assessments Review Presentation
PDF
Delivering a Holistic Approach to Problem Solving in Education from a Multicu...
PPTX
презентация Microsoft office power point
PPTX
Beauty in Comparison Presentation
PPTX
Biological Bases of Yoga and Meditation Therapy Presentation
Biological Bases of Meditation and Yoga Therapy
веселое путешествие
Do I Have Your Attention: Examining the Influence of Unconscious Memories on ...
Mentoring101
Exploring A Holistic Multicultural Approach to Problem Solving in Education P...
Biological Bases of Meditation and Yoga Therapy Supplemental Report
инфракрасное излучение
Honors and Awards
Plan de afaceri ricop sme - 31 may
Arondare strazi cls1 2012 2013
Ig5 brief 2 in salford and proud
презентация Microsoft power point
Comparing Pharmacological VS Psychedelic Treatments for Anxiety Disorders
Re:Mark{able} Females: Sexual Pleasures, Risks and Rewards of Tattoos, Genita...
How Useful Are Sexual Recidivism Assessments Review Presentation
Delivering a Holistic Approach to Problem Solving in Education from a Multicu...
презентация Microsoft office power point
Beauty in Comparison Presentation
Biological Bases of Yoga and Meditation Therapy Presentation
Ad

Recently uploaded (20)

PDF
想要安全提高成绩?我们的黑客技术采用深度伪装和多层加密手段,确保你的信息安全无忧。价格公道,流程简单,同时提供全面的信息保护和事后痕迹清理,让你轻松提升G...
PPTX
3分钟读懂利物浦约翰摩尔大学毕业证LJMU毕业证学历认证
PPTX
3分钟读懂曼彻斯特大学毕业证UoM毕业证学历认证
PPTX
3分钟读懂诺里奇艺术大学毕业证NUA毕业证学历认证
PPTX
3分钟读懂拉夫堡大学毕业证LU毕业证学历认证
PPTX
3分钟读懂曼彻斯特城市大学毕业证MMU毕业证学历认证
PPTX
模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板
PPTX
3分钟读懂伦敦大学学院毕业证UCL毕业证学历认证
PPTX
3分钟读懂福特汉姆大学毕业证Fordham毕业证学历认证
PDF
01_Course_Introduction(20210916課後更新).pdf
PPTX
3分钟读懂肯塔基大学毕业证UK毕业证学历认证
PPTX
3分钟读懂佩珀代因大学毕业证Pepperdine毕业证学历认证
PDF
黑客出手,分数我有!安全可靠的技术支持,让你的GPA瞬间提升,留学之路更加顺畅!【微信:viphuzhao】
PDF
黑客技术,安全提分不是梦!我们采用最新的数据破解和隐藏技术,精准定位并修改你的成绩,同时采用深度隐藏技术确保你的操作不被发现。价格实惠,流程快速,事后无痕...
PPTX
3分钟读懂圭尔夫大学毕业证U of G毕业证学历认证
PPTX
《HSK标准教程4下》第15课课件new.pptx HSK chapter 15 pptx
PPTX
3分钟读懂贵湖大学毕业证U of G毕业证学历认证
PPTX
3分钟读懂纽曼大学毕业证Newman毕业证学历认证
PPTX
3分钟读懂伦敦商学院毕业证LBS毕业证学历认证
PPTX
3分钟读懂南威尔士大学毕业证UCB毕业证学历认证
想要安全提高成绩?我们的黑客技术采用深度伪装和多层加密手段,确保你的信息安全无忧。价格公道,流程简单,同时提供全面的信息保护和事后痕迹清理,让你轻松提升G...
3分钟读懂利物浦约翰摩尔大学毕业证LJMU毕业证学历认证
3分钟读懂曼彻斯特大学毕业证UoM毕业证学历认证
3分钟读懂诺里奇艺术大学毕业证NUA毕业证学历认证
3分钟读懂拉夫堡大学毕业证LU毕业证学历认证
3分钟读懂曼彻斯特城市大学毕业证MMU毕业证学历认证
模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板
3分钟读懂伦敦大学学院毕业证UCL毕业证学历认证
3分钟读懂福特汉姆大学毕业证Fordham毕业证学历认证
01_Course_Introduction(20210916課後更新).pdf
3分钟读懂肯塔基大学毕业证UK毕业证学历认证
3分钟读懂佩珀代因大学毕业证Pepperdine毕业证学历认证
黑客出手,分数我有!安全可靠的技术支持,让你的GPA瞬间提升,留学之路更加顺畅!【微信:viphuzhao】
黑客技术,安全提分不是梦!我们采用最新的数据破解和隐藏技术,精准定位并修改你的成绩,同时采用深度隐藏技术确保你的操作不被发现。价格实惠,流程快速,事后无痕...
3分钟读懂圭尔夫大学毕业证U of G毕业证学历认证
《HSK标准教程4下》第15课课件new.pptx HSK chapter 15 pptx
3分钟读懂贵湖大学毕业证U of G毕业证学历认证
3分钟读懂纽曼大学毕业证Newman毕业证学历认证
3分钟读懂伦敦商学院毕业证LBS毕业证学历认证
3分钟读懂南威尔士大学毕业证UCB毕业证学历认证

Spring中的object xml映射详解

  • 1. Spring 作为 Java 应用程序框架,已在 Java 开发社区中得到广泛使用,SpringSource 近日发布了最新 版本 Spring 3.0.1 版本。文章主要针对 Spring 中的 Object/XML 映射,分析使用 Object/XML 映射的特性 与优势。 Spring 以其流行的科技词汇而著名, “dependencyinjection 依赖项注入) 、 比如 ( ”“inversionofcontrol (控制反转)和 ”“aspect-orientedprogramming 面向方面编程)等。 ( ” 它还支持 Model-View-Controller(MVC) 模式,很好地兼容用于数据访问的各种数据库驱动程序。 另外,它支持事务处理、单元测试、批处理和安全性。鉴于 Spring 的良好声誉和悠久历史,它通常是 应用程序快速开发的首选框架。但是,最大的好处也许是:Spring 是免费的。 Object/XML 映射是什么? Spring 3.0 的一个新特性是 O/XMapper。O/X 映射器这个概念并不新鲜,O 代表 Object,X 代表 XML。它 的目的是在 Java 对象(几乎总是一个 plainoldJavaobject,或简写为 POJO)和 XML 文档之间来回转换。 例如,您可能有一个带有几个属性的简单 bean,且您的业务需要将那个 Java 对象转换为一个 XML 文档。 Spring 的 O/XMapper 能够为您解决那个问题。如果反过来,您需要将一个 XML 文档转换为一个简单 Javabean,Spring 的 O/XMapper 也能胜任,有一点需要注意:SpringO/XMapper 只是定义由流行的第三方 框架实现的统一的界面。要利用 Spring 的 O/X 功能,您需要一个在 Java 对象和 XML 之间来回转换的实用 程序。Castor 就是这样一个流行的第三方工具,本文将使用这个工具。其他这样的工具包括 XMLBeans、 JavaArchitectureforXMLBinding(JAXB)、JiBX 和 XStream。 编组和解组 进行 O/X 映射时,您经常会看到编组(marshalling)和解组(unmarshalling)这两个术语。编组指将 Javabean 转换成 XML 文档的过程,这意味着 Javabean 的所有字段和字段值都将作为 XML 元素或属性填充 到 XML 文件中。有时,编组也称为序列化(serializing)。 如您所料,解组是与编组完全相反的过程,即将 XML 文档转换为 Javabean,这意味着 XML 文档的所有元 素或属性都作为 Java 字段填充到 Javabean 中。有时,解组也称为反序列化(deserializing)。 使用 Spring 的 O/XMapper 的好处 使用 Spring 的 O/XMapper 的一个最直接的好处是可以通过利用 Spring 框架的其他特性简化配置。 Spring 的 bean 库支持将实例化的 O/X 编组器注入(即前面提到过的“依赖项注入”)使用那些编组器的对象。重 申一遍,这将加快应用程序开发和部署。 遵循坚实的面向对象的设计实践,Spring Object/XML 框架只定义两个接口:Marshaller 和 Unmarshaller,它们用于执行 O/X 功能,这是使用这个框架的另一个重大好处。这些接口的实现完全对独 立开发人员开放,开发人员可以轻松切换它们而无需修改代码。例如,如果您一开始使用 Castor 进行 O/X 转换,但后来发现它缺乏您需要的某个功能,这时您可以切换到 XMLBeans 而无需任何代码更改。唯一需要 做的就是更改 Spring 配置文件以使用新的 Object/XML 框架。 使用 Spring 的 Object/XML 映射的另一个好处是统一的异常层次结构。Spring 框架遵循使用它的数据访 问模块建立的模式,方法是将原始异常对象包装到 Spring 自身专为 O/XMapper 建立的运行时异常中。由于
  • 2. 第三方提供商抛出的原始异常被包装到 Spring 运行时异常中,您能够查明出现异常的根本原因。您也不必 费心修改代码以捕获异常,因为异常已包装到一个运行时异常中。以下几个运行时异常扩展了基础异常 XMLMappingException:GenericMarshallingFailureException、ValidationFailureException、 MarshallingFailureException 和 UnmarshallingFailureException。 一个简单的演示 现在您已经了解了 Spring 的 O/XMapper 的背景和基础知识,可以检验它的使用方法了。在本文中,您 首先创建一个简单的 Spring 应用程序,该程序独立于任何 JavaEnterprise 依赖项。然后,您创建一个简 单的 Java 类,它访问 Spring 的配置文件来实例化该类并注入 O/X 依赖项。参见下载部分获取所有源代码 文件(包括配置文件)的链接。 编码 首先应该注意 Spring 配置文件。清单 1 是应用程序用于执行编组和解组操作的配置文件。注意,这个 文件必须在运行时位于类路径中,清单 1.配置文件: 1. <beansxmlnsbeansxmlns="http://www.springframework.org/schema/beans" 2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3. xsi:schemaLocation="http://www.springframework.org/schema/beans 4. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> 5. 6. <beanidbeanid="oxmExample"class="com.xyz.OXMExample"> 7. <propertynamepropertyname="marshaller"ref="castorMarshaller"/> 8. <propertynamepropertyname="unmarshaller"ref="castorMarshaller"/> 9. </bean> 10. <beanidbeanid="castorMarshaller"class="org.springframework.oxm.castor.CastorMarshall er"> 11. <propertynamepropertyname="mappingLocation"value="classpath:mapping.xml"/> 12. </bean> 13. </beans> 如您所见,这个配置文件只定义了两个 bean,这是为了简便起见。第一个 bean 是用于执行演示的类: com.xyz.OXMExample。与该类关联的两个属性使用依赖项注入,它们都使用 castorMarshallerbean 的一个 实例注入。这是在 Spring 框架中定义 bean 的标准方法,经验丰富的 Spring 开发人员很快就会意识到这一 点。 另一个 bean 是 castorMarshallerbean 本身, 它是 org.springframework.oxm.castor.CastorMarshaller 的一个实例,org.springframework.oxm.castor.CastorMarshaller 主要用于包装 Castor 框架。如前所述, 使用 Spring 的 Object/XML 功能需要使用一个第三方 O/X 框架。在本例中,这个第三方产品是 Castor。还 要注意,有一个属性使用 castorMarshaller 定义,那是用于在 Javabean 和 XML 输出之间来回映射的映射 文件。这个文件称为 mapping.xml,它必须在运行时位于类路径中。我将稍后解释 mapping.xml 文件的内 容。清单 2 实际执行 O/X 映射器的代码的部分清单。它是一个简单的 Java 类,清单 2.OXMExample 类: 1. publicclassOXMExample{
  • 3. 2. privatestaticfinalStringFILE_NAME="simplebean.xml"; 3. privateSimpleBeansimpleBean; 4. 5. privateMarshallermarshaller; 6. privateUnmarshallerunmarshaller; 7. 8. publicvoidsetMarshaller(Marshallermarshaller){ 9. this.marshaller=marshaller; 10. } 11. 12. publicvoidsetUnmarshaller(Unmarshallerunmarshaller){ 13. this.unmarshaller=unmarshaller; 14. } 15. 16. publicvoidsaveSimpleBean()throwsIOException{ 17. FileOutputStreamos=null; 18. try{ 19. os=newFileOutputStream(FILE_NAME); 20. this.marshaller.marshal(simpleBean,newStreamResult(os)); 21. }finally{ 22. if(os!=null){ 23. os.close(); 24. } 25. } 26. } 27. 28. publicvoidloadSimpleBean()throwsIOException{ 29. FileInputStreamis=null; 30. try{ 31. is=newFileInputStream(FILE_NAME); 32. this.simpleBean 33. =(SimpleBean)this.unmarshaller.unmarshal(newStreamSource(is)); 34. }finally{ 35. if(is!=null){ 36. is.close(); 37. } 38. } 39. } 40. 41. publicstaticvoidmain(String[]args)throwsIOException{ 42. ApplicationContextappContext 43. =newClassPathXmlApplicationContext("applicationContext.xml"); 44. OXMExampleex=(OXMExample)appContext.getBean("oxmExample"); 45. ex.go();
  • 4. 46. } 47. 48. privatevoidgo()throwsIOException{ 49. simpleBean=getSimpleBean(); 50. 51. saveSimpleBean(); 52. loadSimpleBean(); 53. 54. System.out.println("name:"+simpleBean.getName()); 55. System.out.println("jobdescription:"+simpleBean.getJobDescription()); 56. System.out.println("age:"+simpleBean.getAge()); 57. System.out.println("executive:"+simpleBean.isExecutive()); 58. } 59. 60. 61. privateSimpleBeangetSimpleBean(){ 62. SimpleBeansimpleBean=newSimpleBean(); 63. simpleBean.setAge(35); 64. simpleBean.setExecutive(false); 65. simpleBean.setJobDescription("Janitor"); 66. simpleBean.setName("MisterJones"); 67. 68. returnsimpleBean; 69. 70. } 71. } 要解释清单 2,必须首先介绍 main 方法,因为该方法将先执行。然后再接着介绍清单 2,首先,在 main 方 法中,您的代码捕获 Spring 应用程序的上下文,就是您在清单 1 中看到的配置文件。这个文件必须在类路 径中,否则运行代码将产生一个异常。 当您获得应用程序上下文时,OXMExample 的一个实例从该配置文件中提供的定义创建。注意,这个 bean 在代码中的名称(oxmExample)与配置文件中定义的名称(见清单 1)一致。创建 OXMExample 的一个实例 后,调用 go()方法。这有点反常,因为 Spring 框架实例化一个已经从命令行运行的对象,但那只是为了 实现演示目的而进行的简化。go()方法在打印结果数据前完成 3 个任务: 1.创建 SimpleBean 的一个实例。 2.编组该实例。 3.解组从编组创建的 XML 文档。 您使用 getSimpleBean()方法实例化一个包含一个虚拟员工的信息的 SimpleBean 对象。这个信息包含年 龄(一个整数)、工作描述(一个字符串)、姓名(一个字符串)和该员工是否是执行官(一个布尔型)。
  • 5. 您使用测试数据和返回调用者的返回对象(在本例中为 go()方法)填充字段。您在编组发生时将这个 bean 写入一个 XML 文件,在解组发生时读取那个 XML 文件的内容。 saveSimpleBean()方法执行编组。首先,您获得一个指向 simplebean.xml 的对象,然后,您使用编组 器对象(通过 Spring 的依赖项注入实例化)调用 marshal 方法。这个方法需要两个参数: ◆要被编组的对象(本例中为 SimpleBean 实例) ◆一个 StreamResult 对象,它基本上表示一个 XML 输出抽象 loadSimpleBean()方法执行解组。首先,您获取一个指向 simplebean.xml 的 FileInputStream 对象, 然后,您使用解组器对象(通过 Spring 的依赖项注入实例化)调用 unmarshal 方法。唯一需要的参数是一 个包装 FileInputStream 对象的 StreamSource 对象。注意,解组将创建一个泛型对象,因此您必须将其显 式设置为 SimpleBean 类型。 即使这个类和 Spring 配置文件已经就绪,您也还没有准备好运行这段代码。还记得清单 1 中的映射文 件吗?您还需要定义那个映射文件。定义代码如清单 3 所示,而且,再说一遍,它也必须在运行时位于类 路径中。清单 3.mapping.xml 文件: 1. <mapping> 2. <classnameclassname="com.xyz.SimpleBean"> 3. <map-toxmlmap-toxml="simplebean"/> 4. <fieldnamefieldname="age"type="integer"> 5. <bind-xmlnamebind-xmlname="age"node="element"/> 6. </field> 7. <fieldnamefieldname="executive"type="boolean"> 8. <bind-xmlnamebind-xmlname="is-executive"node="element"/> 9. </field> 10. <fieldnamefieldname="jobDescription"type="string"> 11. <bind-xmlnamebind-xmlname="job"node="element"/> 12. </field> 13. <fieldnamefieldname="name"type="string"> 14. <bind-xmlnamebind-xmlname="name"node="element"/> 15. </field> 16. </class> 17. </mapping> 清单 3 中的映射文件特定于 Object/XML 映射的 Castor 实现。第一个元素(class)定义要映射到一个 XML 输出的类。您必须指定完整路径,map-to 元素提供 XML 文件的根元素的名称。这很重要,因为 XML 规 范规定,每个 XML 文件必须有一个根元素。 每个 field 元素都将被映射到 SimpleBean 类中的一个特定字段。每个 field 元素的 bind-xml 子元素用 于指定关于该字段的特定于 XML 的信息,如对应的 XML 元素的名称,每个字段的值应该是一个元素值还是 一个属性值。如您所见,在本例中,所有值都是元素值。
  • 6. 测试 尽管代码已经编写完成,但在执行这个应用程序之前,您必须处理一些依赖项,特定于 Spring 的依赖 项有: 1. org.springframework.asm-3.0.0.M4.jar 2. org.springframework.beans-3.0.0.M4.jar 3. org.springframework.context-3.0.0.M4.jar 4. org.springframework.core-3.0.0.M4.jar 5. org.springframework.expression-3.0.0.M4.jar 6. org.springframework.oxm-3.0.0.M4.jar 特定于 Castor 的依赖项有: 1. castor-1.3-core.jar 2. castor-1.3-xml.jar 您还需要 commons-logging-1.1.1.jar 和 log4j-1.2.15.jar,因为 Spring 框架需要它们,所有这些 JavaArchive(JAR)文件必须在运行时位于类路径中。如果您在没有这些依赖项的情况下试图运行代码,您 很可能会收到一个异常,指出某个类没有找到。如果遇到这种情况,只需双击您的类路径,确保所有的必 要依赖项已就绪。事实上,要成功编译这段代码,您需要大部分 JAR 文件。 您可以使用您钟爱的 IDE 或只是使用命令行来运行 OXMExample.class。要从命令行运行,只需从您的工 作目录输入 java-cp[classpath]OXMExample,这里的[classpath]是指向刚才提到的所有依赖项(JAR 文件 和配置文件)的类路径。首次运行该程序后,一个名为 simplebean.xml 的新文件将出现在您的工作目录中。 该文件的内容应该如清单 4 所示,清单 4.simplebean.xml 文件: 1. <?xmlversionxmlversion="1.0"encoding="UTF-8"?> 2. <simplebean> 3. <age>35</age> 4. <is-executive>false</is-executive> 5. <job>Janitor</job> 6. <name>MisterJones</name> 7. </simplebean> 清单 4 显示了来自应用程序的编组端的输出,而清单 5 则显示来自应用程序的解组端的结果,这些结果 将在您的控制台中显示,清单 5.解组输出: 1. name:MisterJones 2. jobdescription:Janitor 3. age:35 4. executive:false
  • 7. 现在,您已经成功地完成了您的首次 SpringO/X 映射测试,现在最好做开发人员应该做的工作:修改代 码。向类添加字段并将它们映射到 XML 文件。删除一些字段并将它们从 XML 文件中移除。参考 Castor 文档, 尝试一些更复杂的工作,比如嵌套元素。您可以随心所欲地尝试各种可能性。 结束语 Spring 的 O/X 映射接口是 Spring 框架的强大特性。借助它,您不仅可以将 XML 文档转换为 Java 对象, 还可以将 Java 对象转换为 XML 文档。它利用 Spring 的一个关键优势:依赖项注入。通过结合使用依赖项 注入和 Spring 的 O/XMapper,您可以轻松开发一个解决方案,该方案可以使用任一 O/X 实现,比如 Castor、 XBeans、JiBX、JAXB 和 XStream。由于各个特定实现是 Spring 强大的 InversionofControl 容器的一部分, 开发人员可以在多个特定 O/X 实现之间轻松切换而无需修改代码。 Spring 的 O/XMapper 还向开发人员提供一个统一的异常层次结构,这意味着不管您使用哪个第三方实 现,抛出的运行时异常都是相同的。再强调一次,这将有利于在多个 O/X 供应商之间切换,在 Java 开发社 区中,提供 XML 支持的 Java 应用程序非常热门并且 Spring 框架被广泛使用,因此 Spring 的 O/XMapper 将 受到全世界 Java 应用程序开发人员的欢迎。