天天看點

Spring 對象XML映射

OXM簡介

我們都知道對象關系映射(ORM),用來将Java對象和關系型資料庫的資料進行映射。Spring也提供了一套類似的映射機制,用來将Java對象和XML檔案進行映射。這就是Spring的對象XML映射功能,有時候也成為XML的序列化和反序列化。

這套功能的最基本的兩個接口就是

org.springframework.oxm.Marshaller

org.springframework.oxm.Unmarshaller

,前者用于将Java對象轉換成XML檔案,後者用于将XML檔案轉換成Java對象。

Marshaller接口如下,它有一個marshal方法,包含要序列化的對象,結果會傳回到Result參數上。Result也是一個接口,相應的有幾個實作DOMResult、SAXResult和StreamResult,代表幾種不同的XML技術。

public interface Marshaller {

    void marshal(Object graph, Result result) throws XmlMappingException, IOException;
}
           

Unmarshaller

接口也是類似的,它有一個unmarshal方法,将傳入的Source反序列化Java對象。相應的Source也有三個實作DOMSource、SAXSource和StreamSource,代表這幾種技術。

public interface Unmarshaller {

    Object unmarshal(Source source) throws XmlMappingException, IOException;
}
           

基本使用

要使用Spring的OXM功能,需要添加它的依賴。如果使用Gradle,添加下面的依賴項。

compile group: 'org.springframework', name: 'spring-oxm', version: '4.3.6.RELEASE'

           

Spring提供了幾個Marshaller和Unmarshaller接口的實作,用來進行各種轉換操作。我們來使用最簡單的一個轉換器CastorMarshaller,它同時實作了Marshaller和Unmarshaller接口,是以我們可以使用它同時進行序列化和反序列化。同時它不需要其他額外配置。在配置檔案中,聲明如下一個Bean。

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

我們來定義一個實體類來進行XML序列化和反序列化,方法已省略,隻列出字段。

public class User {
    private int id;
    private String name;
    private int age;
}
           

然後我們使用一個方法來測試

public class OXMTest {

    private static ApplicationContext context;
    private static User user;

    @BeforeClass
    public static void init() {
        context = new ClassPathXmlApplicationContext("classpath:oxm.xml");
        user = new User();
        user.setName("yitian");
        user.setAge(24);
        user.setId(1);
    }

    @Test
    public void test() throws IOException {
        Marshaller marshaller = context.getBean("castorMarshaller", CastorMarshaller.class);
        Unmarshaller unmarshaller = context.getBean("castorMarshaller", CastorMarshaller.class);
        //直接輸出到标準輸出流
        Result result = new StreamResult(System.out);
        marshaller.marshal(user, result);
        System.out.println();

    }
}
           

我們可以在控制台上得到類似下面的輸出。我們可以看到CastorMarshaller預設情況下會将簡單類型處理為屬性,引用類型處理為子元素。

<?xml version="1.0" encoding="UTF-8"?>
<user age="24" id="1"><name>yitian</name></user>
           

各種序列化器

下面來介紹一下Spring實作的一些XML序列化器和反序列化器

JAXB

全稱是Java Architecture for XML Binding,為XML表和Java對象之間提供了快速而簡單的綁定。

org.springframework.oxm.jaxb.Jaxb2Marshaller

同時實作了Marshaller和Unmarshaller,是以我們隻需要配置一個Jaxb2Marshaller即可。使用JAXB,我們需要設定其classesToBeBound屬性指定要綁定哪些類,還可以設定schema屬性提供XML的驗證。JAXB的詳細使用方法請參見其文檔。

<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="classesToBeBound">
            <list>
                <value>foo.bar.Bean1</value>
                <value>foo.bar.Bean2</value>
            </list>
        </property>
        <property name="schema" value="classpath:foo.xsd"/>
    </bean>
           

也可以使用oxm命名空間簡化配置。

<oxm:jaxb2-marshaller id="marshaller">
    <oxm:class-to-be-bound name="foo.bar.Bean1"/>
    <oxm:class-to-be-bound name="foo.bar.Bean2"/>
    ...
</oxm:jaxb2-marshaller>
           

Castor

是一個開源的XML綁定架構。詳細使用方法請參見其文檔。該類庫是一個第三方類庫,是以為了使用它還需要引用其類庫。CastorMarshaller同時實作了Marshaller和Unmarshaller。

預設情況下不需要配置即可使用。如果需要配置XML綁定,我們可以添加一個綁定檔案,綁定檔案如何編寫參見

Castor XML Mapping

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

當然也可以使用oxm命名空間簡化。

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

XMLBeans(已過時)

XMLBeans

也是一個XML綁定工具,但是它的綁定功能需要Java類繼承XmlObject基類。

XmlBeansMarshaller同時實作了Marshaller和Unmarshaller。我們需要添加如下的Bean配置。

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

或者使用oxm命名空間。

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

由于XMLBeans項目已過時,是以Spring相應的XMLBeans類也過時了。

JiBX

.也是一個XML映射類庫,它提供和JDO的對象關系映射類似的功能。

JibxMarshaller同時實作了Marshaller和Unmarshaller。

它的Bean配置檔案如下。我們使用targetClass屬性向其添加要映射的類。

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

或者使用oxm命名空間簡化。

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

JibxMarshaller設計為隻為一個類進行序列化和反序列化。是以如果要序列化多個類,就需要配置多個JibxMarshaller。

XStream

是一個簡單的XML序列化庫。

預設情況下XStream不需要任何配置即可使用。如果需要配置的話,可以使用aliases屬性自定義生成的XML檔案。

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

XStream可以反序列化匿名類,可能會造成安全隐患。是以最好不要使用XStream來反序列化外部加載的XML(例如網絡上的XML)。我們還可以使用supportedClasses屬性注冊類,這樣會確定我們隻反序列化注冊的類。

<bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
    <property name="supportedClasses" value="foo.Bar"/>
    ...
</bean>
           

另外需要注意XStream隻是一個XML序列化庫,而不是資料綁定庫。也就是說它的功能不如前面幾個庫完善,有些命名空間不支援。是以你無法用XStream來完成類似Web服務的功能。