Spring Object到XML對映範例

2019-10-16 22:11:41
Spring的Object/XML對映將物件轉換到XML,或反之亦然。這個過程也被稱為
  1. XML Marshalling – 轉換物件到XML
  2. XML UnMarshalling – 轉換XML到物件

在本教學中,我們將介紹如何使用 Spring 的 OXM 來做轉換, Object <--- Spring oxm ---> XML.

註: 為什麼使用 Spring的OXM 有好處?請閱讀本 Spring 物件/XML對映的文章

這裡我們建立一個 Java 工程,整個工程的目錄如下所示:

1. 一個簡單物件

一個簡單的物件,之後將其轉換成 XML 檔案。
package com.yiibai.core.model;

public class Customer {

	String name;
	int age;
	boolean flag;
	String address;

	//standard getter, setter and toString() methods.
}

3. Marshaller 和 Unmarshaller

這個類將處理通過 Spring 的 OXM 介面的轉換: Marshaller 和 Unmarshaller.

package com.yiibai.core;

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.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;

public class XMLConverter {

	private Marshaller marshaller;
	private Unmarshaller unmarshaller;

	public Marshaller getMarshaller() {
		return marshaller;
	}

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

	public Unmarshaller getUnmarshaller() {
		return unmarshaller;
	}

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

	public void convertFromObjectToXML(Object object, String filepath)
		throws IOException {

		FileOutputStream os = null;
		try {
			os = new FileOutputStream(filepath);
			getMarshaller().marshal(object, new StreamResult(os));
		} finally {
			if (os != null) {
				os.close();
			}
		}
	}

	public Object convertFromXMLToObject(String xmlfile) throws IOException {

		FileInputStream is = null;
		try {
			is = new FileInputStream(xmlfile);
			return getUnmarshaller().unmarshal(new StreamSource(is));
		} finally {
			if (is != null) {
				is.close();
			}
		}
	}

}

4. Spring組態

在 Spring 的 bean 組態檔案,注入 CastorMarshaller 作為 XML 係結框架。
<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="XMLConverter" class="com.yiibai.core.XMLConverter">
		<property name="marshaller" ref="castorMarshaller" />
		<property name="unmarshaller" ref="castorMarshaller" />
	</bean>
	<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller" />

</beans>

5. 測試

執行它 

package com.yiibai.core;

import java.io.IOException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.yiibai.core.model.Customer;

public class App {
	private static final String XML_FILE_NAME = "customer.xml";
	
	public static void main(String[] args) throws IOException {
		ApplicationContext appContext = new ClassPathXmlApplicationContext("App.xml");
		XMLConverter converter = (XMLConverter) appContext.getBean("XMLConverter");
		
		Customer customer = new Customer();
		customer.setName("yiibai");
		customer.setAge(28);
		customer.setFlag(true);
		customer.setAddress("Haikou haidiandao");
		
		System.out.println("Convert Object to XML!");
		//from object to XML file
		converter.convertFromObjectToXML(customer, XML_FILE_NAME);
		System.out.println("Done \n");
		
		System.out.println("Convert XML back to Object!");
		//from XML to object
		Customer customer2 = (Customer)converter.convertFromXMLToObject(XML_FILE_NAME);
		System.out.println(customer2);
		System.out.println("Done");
		
	}
}

輸出結果

Convert Object to XML!
Done 

Convert XML back to Object!
Customer [name=yiibai, age=28, flag=true, address=Haikou Haidiandao]
Done
下面的 XML 檔案「customer.xml」將在專案的根檔案夾中生成。

File : customer.xml

<?xml version="1.0" encoding="UTF-8"?>
<customer flag="true" age="28">
	<address>Haikou Haidiandao</address>
	<name>yiibai</name>
</customer>

XML對映

等等,為什麼flag和age可轉換為屬性?這是一種來控制哪些欄位應為屬性或元素的使用的方式? 當然,您可以使用 Castor XML對映定義物件 和XML之間的關係。

建立以下對映檔案,並把它放到你的專案的 classpath。

File : mapping.xml

<mapping>
	<class name="com.yiibai.core.model.Customer">

		<map-to xml="customer" />

		<field name="age" type="integer">
			<bind-xml name="age" node="attribute" />
		</field>

		<field name="flag" type="boolean">
			<bind-xml name="flag" node="element" />
		</field>

		<field name="name" type="string">
			<bind-xml name="name" node="element" />
		</field>

		<field name="address" type="string">
			<bind-xml name="address" node="element" />
		</field>
	</class>
</mapping>
在Spring bean組態檔案,上述通過「mappingLocation」注入 mapping.xml 到 CastorMarshaller 。註:這裡需要加入一個 org.springframework.oxm.***.jar 包,這個包函式在 MyEclipse 庫的 Spring 3.0 Web Libaries中。
<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="XMLConverter" class="com.yiibai.core.XMLConverter">
		<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>
再次測試,XML檔案「customer.xml」將被更新。

File : customer.xml

<?xml version="1.0" encoding="UTF-8"?>
<customer age="28">
	<flag>true</flag>
	<name>yiibai</name>
	<address>Haikou Haidiandao</address>
</customer>