21. 使用O / X Mappers编组XML

21.1 简介

在本章中,我们将描述Spring的Object / XML Mapping支持。对象/ XML映射(简称O / X映射)是将XML文档转换为对象或从对象转换XML文档的行为。此转换过程也称为XML编组或XML序列化。本章可互换使用这些术语。

在O / X映射领域,marshaller负责将对象(图形)序列化为XML。以类似的方式,unmarshaller将XML反序列化为对象图。此XML可以采用DOM文档,输入或输出流或SAX处理程序的形式。

使用Spring满足O / X映射需求的一些好处是:

21.1.1 易于配置

Spring的bean工厂可以轻松配置marshallers,无需构建JAXB上下文,JiBX绑定工厂等。可以将marshallers配置为应用程序上下文中的任何其他bean。此外,基于XML命名空间的配置可用于许多marshallers,使配置更简单。

21.1.2 一致的接口

Spring的O / X映射通过两个全局接口运行: MarshallerUnmarshaller 接口。这些抽象允许您相对轻松地切换O / X映射框架,对执行编组的类几乎不需要进行任何更改。这种方法的另一个好处是可以使用混合和匹配方法(例如,使用JAXB执行某些编组,其他使用XMLBeans)以非侵入方式进行XML编组,从而充分利用每种技术的优势。

21.1.3 一致的异常层次结构

Spring提供从底层O / X映射工具的异常到其自己的异常层次结构的转换,其中 XmlMappingException 作为根异常。可以预料,这些运行时异常会包装原始异常,因此不会丢失任何信息。

21.2 Marshaller和Unmarshaller

如简介中所述,marshaller将对象序列化为XML,而unmarshaller将XML流反序列化为对象。在本节中,我们将描述用于此目的的两个Spring接口。

21.2.1 Marshaller

Spring抽象了 org.springframework.oxm.Marshaller 接口后面的所有编组操作,其主要方法如下所示。

public interface Marshaller {

    /**
     * Marshal the object graph with the given root into the provided Result.
     */
    void marshal(Object graph, Result result) throws XmlMappingException, IOException;
}

Marshaller 接口有一个main方法,它将给定对象封送到给定的 javax.xml.transform.Result 。 Result是一个标记接口,基本上表示XML输出抽象:具体实现包装各种XML表示,如下表所示。

结果实现包装XML表示
DOMResultorg.w3c.dom.Node
SAXResultorg.xml.sax.ContentHandler
StreamResultjava.io.Filejava.io.OutputStream ,或 java.io.Writer

尽管marshal()方法接受普通对象作为其第一个参数,但大多数Marshaller实现都无法处理任意对象。相反,对象类必须映射到映射文件中,标记有注释,向编组器注册,或者具有公共基础类。请参阅本章的其他部分,以确定您选择的O / X技术如何管理。

21.2.2 Unmarshaller

Marshaller 类似,有 org.springframework.oxm.Unmarshaller 接口。

public interface Unmarshaller {

    /**
     * Unmarshal the given provided Source into an object graph.
     */
    Object unmarshal(Source source) throws XmlMappingException, IOException;
}

此接口还有一个方法,它从给定的 javax.xml.transform.Source (XML输入抽象)中读取,并返回读取的对象。与Result一样,Source是一个标记接口,具有三个具体实现。每个包装不同的XML表示,如下表所示。

源代码实现包装XML表示
DOMSourceorg.w3c.dom.Node
SAXSourceorg.xml.sax.InputSourceorg.xml.sax.XMLReader
StreamSourcejava.io.Filejava.io.InputStream ,或 java.io.Reader

即使有两个单独的编组接口( MarshallerUnmarshaller ),Spring-WS中的所有实现都在一个类中实现。这意味着你可以连接一个marshaller类并将它作为marshaller和unmarshaller引用到你的 applicationContext.xml 中。

21.2.3 XmlMappingException

Spring将基础O / X映射工具中的异常转换为其自己的异常层次结构,并将 XmlMappingException 作为根异常。可以预料,这些运行时异常会包装原始异常,因此不会丢失任何信息。

此外, MarshallingFailureExceptionUnmarshallingFailureException 提供了编组和解组操作之间的区别,即使底层的O / X映射工具不这样做。

O / X Mapping异常层次结构如下图所示:

oxm exceptions

O / X映射异常层次结构

21.3 使用Marshaller和Unmarshaller

Spring的OXM可用于各种情况。在下面的示例中,我们将使用它将Spring托管应用程序的设置编组为XML文件。我们将使用一个简单的JavaBean来表示设置:

public class Settings {

    private boolean fooEnabled;

    public boolean isFooEnabled() {
        return fooEnabled;
    }

    public void setFooEnabled(boolean fooEnabled) {
        this.fooEnabled = fooEnabled;
    }
}

应用程序类使用此bean来存储其设置。除了main方法之外,该类还有两个方法: saveSettings() 将设置bean保存到名为 settings.xml 的文件中, loadSettings() 再次加载这些设置。 main() 方法构造Spring应用程序上下文,并调用这两个方法。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;

public class Application {

    private static final String FILE_NAME = "settings.xml";
    private Settings settings = new Settings();
    private Marshaller marshaller;
    private Unmarshaller unmarshaller;

    public void setMarshaller(Marshaller marshaller) {
        this.marshaller = marshaller;
    }

    public void setUnmarshaller(Unmarshaller unmarshaller) {
        this.unmarshaller = unmarshaller;
    }

    public void saveSettings() throws IOException {
        FileOutputStream os = null;
        try {
            os = new FileOutputStream(FILE_NAME);
            this.marshaller.marshal(settings, new StreamResult(os));
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }

    public void loadSettings() throws IOException {
        FileInputStream is = null;
        try {
            is = new FileInputStream(FILE_NAME);
            this.settings = (Settings) 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");
        Application application = (Application) appContext.getBean("application");
        application.saveSettings();
        application.loadSettings();
    }
}

Application 需要设置 marshallerunmarshaller 属性。我们可以使用以下 applicationContext.xml 这样做:

<beans>
    <bean id="application" class="Application">
        <property name="marshaller" ref="castorMarshaller" />
        <property name="unmarshaller" ref="castorMarshaller" />
    </bean>
    <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
</beans>

此应用程序上下文使用Castor,但我们可以使用本章后面介绍的任何其他marshaller实例。请注意,默认情况下Castor不需要任何进一步的配置,因此bean定义相当简单。另请注意, CastorMarshaller 同时实现 MarshallerUnmarshaller ,因此我们可以在应用程序的 marshallerunmarshaller 属性中引用 castorMarshaller bean。

此示例应用程序生成以下 settings.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<settings foo-enabled="false"/>

21.4 XML配置命名空间

可以使用来自OXM名称空间的标签更简洁地配置Marshallers。要使这些标记可用,必须首先在XML配置文件的前导码中引用相应的模式。请注意下面的'oxm'相关文字:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:oxm="http://www.springframework.org/schema/oxm" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd">

目前,可以使用以下标签:

每个标签将在其各自的编组部分中进行说明。作为一个例子,这里是JAXB2编组器的配置可能如下所示:

<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>

21.5 JAXB

JAXB绑定编译器将W3C XML Schema转换为一个或多个Java类,一个 jaxb.properties 文件,以及可能的一些资源文件。 JAXB还提供了一种从带注释的Java类生成模式的方法。

Spring遵循 Section 21.2, “Marshaller and Unmarshaller” 中描述的 MarshallerUnmarshaller 接口,支持JAXB 2.0 API作为XML编组策略。相应的集成类驻留在 org.springframework.oxm.jaxb 包中。

21.5.1 Jaxb2Marshaller

Jaxb2Marshaller 类实现了Spring MarshallerUnmarshaller 接口。它需要一个上下文路径来操作,您可以使用 contextPath 属性进行设置。上下文路径是冒号(:)分隔的Java包名称列表,其中包含模式派生类。它还提供 classesToBeBound 属性,允许您设置marshaller支持的类数组。通过为bean指定一个或多个模式资源来执行模式验证,如下所示:

<beans>
    <bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="classesToBeBound">
            <list>
                <value>org.springframework.oxm.jaxb.Flight</value>
                <value>org.springframework.oxm.jaxb.Flights</value>
            </list>
        </property>
        <property name="schema" value="classpath:org/springframework/oxm/schema.xsd"/>
    </bean>

    ...

</beans>

XML配置命名空间

jaxb2-marshaller 标签配置 org.springframework.oxm.jaxb.Jaxb2Marshaller 。这是一个例子:

<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>

或者,要绑定的类列表可以通过 class-to-be-bound 子标记提供给编组器:

<oxm:jaxb2-marshaller id="marshaller">
    <oxm:class-to-be-bound name="org.springframework.ws.samples.airline.schema.Airport"/>
    <oxm:class-to-be-bound name="org.springframework.ws.samples.airline.schema.Flight"/>
    ...
</oxm:jaxb2-marshaller>

可用属性包括:

属性描述必需
id编组员的身份
contextPathJAXB上下文路径no

21.6 蓖麻

Castor XML映射是一个开源XML绑定框架。它允许您将java对象模型中包含的数据转换为XML文档或从XML文档转换。默认情况下,它不需要任何进一步的配置,但可以使用映射文件来更好地控制Castor的行为。

有关Castor的更多信息,请参阅 Castor web site 。 Spring集成类驻留在 org.springframework.oxm.castor 包中。

21.6.1 CastorMarshaller

与JAXB一样, CastorMarshaller 实现了 MarshallerUnmarshaller 接口。它可以按如下方式连接:

<beans>
    <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller" />
    ...
</beans>

21.6.2 映射

尽管可以依赖Castor的默认编组行为,但可能需要对其进行更多控制。这可以使用Castor映射文件来完成。有关更多信息,请参阅 Castor XML Mapping

可以使用 mappingLocation resource属性设置映射,如下所示,使用类路径资源。

<beans>
    <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller" >
        <property name="mappingLocation" value="classpath:mapping.xml" />
    </bean>
</beans>

XML配置命名空间

castor-marshaller 标记配置 org.springframework.oxm.castor.CastorMarshaller 。这是一个例子:

<oxm:castor-marshaller id="marshaller" mapping-location="classpath:org/springframework/oxm/castor/mapping.xml"/>

marshaller实例可以通过两种方式配置,方法是指定映射文件的位置(通过 mapping-location 属性),或者通过标识存在相应XML描述符类的Java POJO(通过 target-classtarget-package 属性)。后一种方式通常与XML模式的XML代码生成结合使用。

可用属性包括:

属性描述必需
id编组员的身份
encoding用于从XML解组的编码no
target-classPOJO的Java类名,其XML类描述符可用(通过代码生成生成)no
target-package一个Java包名称,用于标识包含POJO及其对应的Castor XML描述符类的包(通过从XML模式生成代码生成)no
mapping-locationCastor XML映射文件的位置no

21.7 XMLBeans

XMLBeans是一种XML绑定工具,具有完整的XML Schema支持,并提供完整的XML Infoset保真度。它采用与大多数其他O / X映射框架不同的方法,因为从XML模式生成的所有类都派生自 XmlObject ,并在其中包含XML绑定信息。

有关XMLBeans的更多信息,请参阅 XMLBeans web site 。 Spring-WS集成类驻留在 org.springframework.oxm.xmlbeans 包中。

21.7.1 XmlBeansMarshaller

XmlBeansMarshaller 实现了 MarshallerUnmarshaller 接口。它可以配置如下:

<beans>

    <bean id="xmlBeansMarshaller" class="org.springframework.oxm.xmlbeans.XmlBeansMarshaller" />
    ...

</beans>

请注意,XmlBeansMarshaller只能封送XmlObject类型的对象,而不是每个java.lang.Object。

XML配置命名空间

xmlbeans-marshaller 标记配置 org.springframework.oxm.xmlbeans.XmlBeansMarshaller 。这是一个例子:

<oxm:xmlbeans-marshaller id="marshaller"/>

可用属性包括:

属性描述必需
id编组人员的身份
options要用于此编组程序的XmlOptions的bean名称。通常 XmlOptionsFactoryBean 定义no

21.8 JiBX

JiBX框架提供了类似于JDO为ORM提供的解决方案:绑定定义定义了Java对象如何转换为XML或从XML转换的规则。准备好绑定并编译类之后,JiBX绑定编译器会增强类文件,并添加代码来处理从XML转换类的实例。

有关JiBX的更多信息,请参阅 JiBX web site 。 Spring集成类驻留在 org.springframework.oxm.jibx 包中。

21.8.1 JibxMarshaller

JibxMarshaller 类同时实现 MarshallerUnmarshaller 接口。要进行操作,需要编组类的名称,您可以使用 targetClass 属性进行设置。 (可选)您可以使用 bindingName 属性设置绑定名称。在下一个示例中,我们绑定 Flights 类:

<beans>
    <bean id="jibxFlightsMarshaller" class="org.springframework.oxm.jibx.JibxMarshaller">
        <property name="targetClass">org.springframework.oxm.jibx.Flights</property>
    </bean>
    ...
</beans>

JibxMarshaller 配置为单个类。如果要编组多个类,则必须使用不同的 targetClass 属性值配置多个 JibxMarshaller

XML配置命名空间

jibx-marshaller 标记配置 org.springframework.oxm.jibx.JibxMarshaller 。这是一个例子:

<oxm:jibx-marshaller id="marshaller" target-class="org.springframework.ws.samples.airline.schema.Flight"/>

可用属性包括:

属性描述必需
id编组人员的身份
target-class此编组的目标类
bindingName此编组使用的绑定名称no

21.9 XStream的

XStream是一个简单的库,用于将对象序列化为XML并再次返回。它不需要任何映射,并生成干净的XML。

有关XStream的更多信息,请参阅 XStream web site 。 Spring集成类驻留在 org.springframework.oxm.xstream 包中。

21.9.1 XStreamMarshaller

XStreamMarshaller 不需要任何配置,可以直接在应用程序上下文中进行配置。要进一步自定义XML,您可以设置analias map,它包含映射到类的字符串别名:

<beans>
    <bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
        <property name="aliases">
            <props>
                <prop key="Flight">org.springframework.oxm.xstream.Flight</prop>
            </props>
        </property>
    </bean>
    ...
</beans>

默认情况下,XStream允许对任意类进行解组,这可能导致不安全的Java序列化效果。因此,不建议使用XStreamMarshaller从外部源(即Web)解组XML,因为这可能导致安全漏洞。如果选择使用XStreamMarshaller从外部源解组XML,请在XStreamMarshaller上设置supportedClasses属性,如下所示:<bean id =“xstreamMarshaller”class =“org.springframework.oxm.xstream.XStreamMarshaller”>
<property name =“supportedClasses”value =“org.springframework.oxm.xstream.Flight”/>
...
</ bean>这将确保只有已注册的类才有资格进行解组。此外,您可以注册自定义转换器,以确保只能对您支持的类进行解组。除了明确支持应支持的域类的转换器之外,您可能还希望将CatchAllConverter添加为列表中的最后一个转换器。因此,不会调用具有较低优先级和可能的安全漏洞的默认XStream转换器。

请注意,XStream是XML序列化库,而不是数据绑定库。因此,它具有有限的命名空间支持。因此,它不适合在Web服务中使用。

Updated at: 5 months ago
20.5.5. 使用JTA事务管理设置JPATable of contentVI. Web
Comment
You are not logged in.

There are no comments.