什么是春天?
Spring是Rod Johnson开发的健壮的Java应用程序框架,已在Java开发社区中得到广泛认可。 它以诸如“依赖注入”,“控制反转”和“面向方面的编程”之类的高科技流行语而闻名。 它还支持Model-View-Controller(MVC)模式,并且可以与各种数据库驱动程序很好地协同工作以进行数据访问。 此外,它支持事务管理,单元测试,批处理和安全性。
考虑到它的声誉和寿命,当需要快速的应用程序开发时,它通常被视为“入门”框架。 而且,也许最重要的是,它是免费的。
什么是O / X映射器?
从Spring 3.0开始,O / X Mapper是一个新功能。 O / X映射器的概念并不新鲜。 O代表对象。 X代表XML。 这个想法是将Java对象(几乎总是一个普通的Java对象或POJO)转换为XML文档,反之亦然。
因此,例如,您可能有一个带有几个属性的简单bean,并且您需要将Java对象转换为XML文档。 Spring的O / X Mapper可以为您解决这个问题。 如果情况确实如此(也就是说,您需要获取一个XML文档并将其转换为简单的Java bean),那么Spring的O / X Mapper也可以解决这个问题。
请注意,此时,Spring O / X Mapper只是定义了由流行的第三方框架实现的一致接口。 要利用Spring的O / X功能,您需要一个实用程序来处理从Java对象到XML的转换,反之亦然。 为此目的,一种流行的第三方工具是Castor,我将在本文中使用它。 其他工具是XMLBeans,用于XML绑定的Java体系结构(JAXB),JiBX和XStream。
编组与解组
您经常会看到与O / X映射结合使用的编组 和解组词。
编组是指将Java bean转换为XML文档的过程。 这意味着所有bean的字段和字段值都作为XML元素或属性填充在创建的XML文件中。 有时,编组也称为序列化 。
您可能会猜到, 解组是完全相反的。 它指的是将XML文档转换为Java bean的过程。 这意味着该文档的所有元素或属性都将填充为Java bean中的Java字段,并且元素或属性的值成为这些字段的值。 有时,取消编组也称为反序列化 。
使用Spring的O / X Mapper的好处
使用Spring的O / X映射器的直接好处是可以利用Spring框架的其他方面来简化配置。 使用Spring的bean工厂,您可以将实例化的O / X编组器直接注入(这是前面提到的“依赖注入”),将其直接注入使用它们的对象中。 重复上一点,这有助于快速进行应用程序开发和部署。
遵循可靠的面向对象设计实践,Spring O / X框架仅定义了两个接口( Marshaller
和Unmarshaller
),用于执行O / X功能。 这是使用该框架的另一个突出好处。 这些接口的实现完全取决于各个开发人员,并且可以轻松切换它们,从而无需更改编码。 例如,如果将Castor用于O / X,但发现它缺少所需的某些功能,则可以改用XMLBeans,而无需更改编码。 您只需更改Spring配置文件即可使用新的O / X框架。
使用Spring的O / X映射器的另一个好处是一致的异常层次结构。 通过将原始异常对象包装在专门为O / X映射器建立的Spring自己的运行时异常中,Spring框架遵循了用其数据访问模块建立的模式。 由于第三方提供程序引发的原始异常包含在Spring运行时异常中,因此您永远不会丢失该异常的根本原因。 您也不必担心更改代码以捕获特定异常,因为它包装在运行时异常中。 基本异常XMLMappingException
由其他几个运行时异常扩展,包括GenericMarshallingFailureException
, ValidationFailureException
, MarshallingFailureException
和UnmarshallingFailureException
。
一个简单的示范
现在您已经了解了Spring O / X Mapper的背景和基础知识,现在该看看如何使用它了。 在本文中,您首先创建一个独立于任何Java Enterprise依赖项的简单Spring应用程序。 您创建一个简单的Java类,该类访问Spring的配置文件以实例化该类并注入O / X依赖项。 然后,使用此类的实例来封送和解封一个简单的Java bean。 有关所有源文件(包括配置文件)的链接,请参见下载 。
编码
首先要注意的是Spring配置文件。 清单1是应用程序用来执行编组和解组的配置文件。 请注意,此文件在运行时必须位于类路径中。
清单1.配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="oxmExample" class="com.xyz.OXMExample">
<property name="marshaller" ref="castorMarshaller" />
<property name="unmarshaller" ref="castorMarshaller" />
</bean>
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller">
<property name="mappingLocation" value="classpath:mapping.xml" />
</bean>
</beans>
如您所见,仅定义了两个bean。 这使事情变得简单。 第一个bean是用于执行演示的类( com.xyz.OXMExample
)。 与该类关联的两个属性使用依赖项注入。 在这两种情况下,都向它们注入castorMarshaller
bean的实例。 有经验的Spring开发人员会立即注意到,这是在Spring框架中定义bean的标准方法。
另一个bean是castorMarshaller
bean本身。 它是org.springframework.oxm.castor.CastorMarshaller
一个实例,该实例实质上包装了Castor框架。 如前所述,要使用Spring的O / X功能,需要第三方O / X框架。 在这种情况下,Castor是首选的第三方产品。 另外,请注意,属性是使用castorMarshaller
定义的。 那是Castor用来将Java bean映射到XML输出,反之亦然的映射文件。 该文件称为mapping.xml,并且在运行时必须位于类路径中。 我将在不久后解释mapping.xml文件的内容。
清单2是将实际执行O / X映射器的代码的缩写清单。 如您所见,这是一个相当简单的Java类。
清单2. OXMExample
类(缩写)
public class OXMExample {
private static final String FILE_NAME = "simplebean.xml";
private SimpleBean simpleBean;
private Marshaller marshaller;
private Unmarshaller unmarshaller;
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
public void setUnmarshaller(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller;
}
public void saveSimpleBean() throws IOException {
FileOutputStream os = null;
try {
os = new FileOutputStream(FILE_NAME);
this.marshaller.marshal(simpleBean, new StreamResult(os));
} finally {
if (os != null) {
os.close();
}
}
}
public void loadSimpleBean() throws IOException {
FileInputStream is = null;
try {
is = new FileInputStream(FILE_NAME);
this.simpleBean
= (SimpleBean) this.unmarshaller.unmarshal(new StreamSource(is));
} finally {
if (is != null) {
is.close();
}
}
}
public static void main(String[] args) throws IOException {
ApplicationContext appContext
= new ClassPathXmlApplicationContext("applicationContext.xml");
OXMExample ex = (OXMExample) appContext.getBean("oxmExample");
ex.go();
}
private void go() throws IOException {
simpleBean = getSimpleBean();
saveSimpleBean();
loadSimpleBean();
System.out.println("name: " + simpleBean.getName());
System.out.println("job description: " + simpleBean.getJobDescription());
System.out.println("age: " + simpleBean.getAge());
System.out.println("executive: " + simpleBean.isExecutive());
}
private SimpleBean getSimpleBean() {
SimpleBean simpleBean = new SimpleBean();
simpleBean.setAge(35);
simpleBean.setExecutive(false);
simpleBean.setJobDescription("Janitor");
simpleBean.setName("Mister Jones");
return simpleBean;
}
}
为了解释清单2 ,我将从main
方法开始,首先执行该方法,然后从那里开始执行代码。
首先,在main
方法中,您的代码将获取Spring应用程序上下文。 这是清单1中所示的配置文件。 该文件必须在类路径中,否则运行代码将生成异常。
获取应用程序上下文时,将从配置文件中提供的定义中创建OXMExample
的实例。 请注意,bean的名称( oxmExample
)在代码中与配置文件中定义的名称完全相同( 清单1 )。 创建OXMExample
实例OXMExample
,调用go()
方法。 这有点不寻常,因为Spring框架实例化了一个已经从命令行运行的对象,但是出于演示的目的,这只是使事情变得简单。
go()
方法在打印出结果数据之前会做三件事:
- 它创建一个
SimpleBean
的实例。 - 然后它将封送该实例。
- 然后,它将解组从编组创建的XML文档。
您可以使用getSimpleBean()
方法实例化一个SimpleBean
对象,该对象包含有关虚构员工的信息。 该信息包括年龄(整数),工作描述(字符串),姓名(字符串)以及员工是否为主管(布尔值)。 您将使用测试数据填充字段,并将返回对象返回给调用方,在本例中为go()
方法。 当编组发生时,您可以将此bean的内容写入XML文件,然后在进行编组时读取该文件的内容。
saveSimpleBean()
方法执行编组。 首先,获得一个指向simplebean.xml的FileOutputStream
对象。 然后,使用marshaller对象(由Spring的依赖注入实例化)调用marshal
方法。 此方法需要两个参数:
- 要编组的对象(在本例中为
SimpleBean
实例) - 一个
StreamResult
对象,该对象基本上表示XML输出抽象
loadSimpleBean()
方法执行解组。 首先,获得一个指向simplebean.xml的FileInputStream
对象。 然后,使用unmarshaller对象(由Spring的依赖注入实例化)调用unmarshal
方法。 唯一需要的参数是包装FileInputStream
对象的StreamSource
对象。 请注意,解组将创建一个通用对象,因此您必须将其显式转换为SimpleBean
类型。
即使有了该类和Spring配置文件,您仍未准备好运行此代码。 还记得清单1中的映射文件吗? 您仍然需要定义它。 如清单3所示,并且再次必须在运行时位于类路径中。
清单3. mapping.xml文件
<mapping>
<class name="com.xyz.SimpleBean">
<map-to xml="simplebean"/>
<field name="age" type="integer">
<bind-xml name="age" node="element"/>
</field>
<field name="executive" type="boolean">
<bind-xml name="is-executive" node="element"/>
</field>
<field name="jobDescription" type="string">
<bind-xml name="job" node="element"/>
</field>
<field name="name" type="string">
<bind-xml name="name" node="element"/>
</field>
</class>
</mapping>
清单3中的映射文件特定于O / X映射的Castor实现。 第一个元素( class
)仅定义要映射到XML输出的类。 您必须指定完整路径。
map-to
元素提供XML文件的根元素的名称。 这很重要,因为XML规范要求每个XML文件必须具有一个根元素。
每个field
元素都映射到SimpleBean
类中的特定字段。 每个field
元素的bind-xml
子元素用于指定有关该字段的XML特定信息,例如相应XML元素的名称以及每个字段的值应为元素值还是属性值。 如您所见,在这种情况下,所有值都是元素值。
测试它
尽管编码已完成,但是在执行此应用程序之前必须解决某些依赖性。
特定于Spring的依赖项是:
- org.springframework.asm-3.0.0.M4.jar
- org.springframework.beans-3.0.0.M4.jar
- org.springframework.context-3.0.0.M4.jar
- org.springframework.core-3.0.0.M4.jar
- org.springframework.expression-3.0.0.M4.jar
- org.springframework.oxm-3.0.0.M4.jar
Castor特定的依赖项是:
- castor-1.3-core.jar
- castor-1.3-xml.jar
您还需要commons-logging-1.1.1.jar和log4j-1.2.15.jar,因为Spring框架需要它们。
所有这些Java Archive(JAR)文件都必须在运行时位于类路径中。 如果您尝试在没有这些依赖项的情况下执行代码,则可能会收到无法找到特定类的异常。 如果是这种情况,只需仔细检查您的类路径以确保所有必需的依赖项都已就绪。 实际上,您需要大多数JAR文件才能成功编译代码。 有关获取这些JAR文件的信息,请参阅相关主题在这篇文章的末尾。
您可以使用自己喜欢的IDE或仅使用命令行运行OXMExample.class
。 要从命令行运行它,只需在工作目录中键入java -cp [classpath] OXMExample ,其中[classpath]
是指向前面提到的所有依赖项(JAR文件和配置文件)的类路径。
首次运行后,一个名为simplebean.xml的新文件应出现在当前工作目录中。 该文件的内容应与清单4相匹配。
清单4. simplebean.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<simplebean>
<age>35</age>
<is-executive>false</is-executive>
<job>Janitor</job>
<name>Mister Jones</name>
</simplebean>
清单4为您提供了来自应用程序编组端的输出,同时您还应该在控制台中看到来自应用程序的编组端的结果。 这应该类似于清单5 。
清单5.解组输出
name: Mister Jones
job description: Janitor
age: 35
executive: false
那里有。 您已经成功完成了第一个Spring O / X映射测试。 恭喜你!
现在是时候做开发人员最擅长的事情了:修补代码。 将字段添加到类中,并将其映射到XML文件。 删除一些字段并将其从XML文件中删除。 请参阅Castor文档,并尝试做更复杂的事情,例如嵌套元素。 您的可能性是无限的。
结论
Spring的O / X映射接口是Spring框架的强大补充。 使用它,您可以将XML文档转换为Java对象,也可以将Java对象转换为XML文档。
它利用了Spring的关键优势之一:依赖注入。 通过将依赖项注入与Spring的O / X Mapper一起使用,您可以轻松地使用多种O / X实现中的任何一种来开发解决方案,例如Castor,XBeans,JiBX,JAXB和XStream。 由于特定的实现是Spring功能强大的Inversion of Control容器的一部分,因此开发人员可以轻松地在特定的O / X实现之间切换,而无需进行代码更改。
Spring的O / X Mapper还为开发人员提供了一致的异常层次结构。 这意味着无论您选择哪个第三方实现,抛出的运行时异常都是相同的。 再次,这有助于在O / X供应商之间进行更改。
鉴于需要XML支持的Java应用程序的需求很高,并且整个Java开发社区都大量使用了Spring框架,因此Spring O / X Mapper对于全球的Java应用程序开发人员来说都是一个受欢迎的选择。
翻译自: https://www.ibm.com/developerworks/java/library/x-springXOM/index.html