OXM 介紹
OXM全名為Objec XML Mapping,主要的功能為 Java Bean 與 XML 之間的轉換工作。Castor 的優點為不需要定義映射檔,比起JAXB更為一項輕量級的應用。 在OXM中有兩項重要的名詞 marshal 與 unmarshal,將 Object 轉換為 XML 的動作稱為 marshal,反之稱為 unmarshal,如此的習慣也在JAXB中出現。 此外,在我實驗的過程中發現 Castor 為採用反射的方式建立物件,因此擁有一項優點為可以任意 unmarshal 物件,即使與原先 marshal 的物件為不同的 Class,增加了許多設計的彈性。
Castor官方網站 http://www.castor.org/
Castor 實作 - Castor 需要的套件
- castor-1.3-core.jar
- castor-1.3-xml.jar
- castor-1.3-xml-schema.jar
下載網址 http://www.castor.org/download.html#Castor 此外 Castor 在執行的時候也需要:
- log4j-1.2.15.jar
- commons-logging-1.1.1.jar
這兩包套件可在Apache網站取得
Marshal 實作
在這個章節中我們測試在物件中存放參數與子物件進行OXM:
- 設計一個 Model
12345private String title;private int num;private Integer sort;private List<SubModel> list;private Hashtable<String,SubModel> table;
- 設計一個SubModel
1private String name;
- Marshal 轉換程式 Object2XML.java
123456789101112131415161718192021222324252627282930313233343536373839404142import java.io.StringWriter;import java.util.ArrayList;import java.util.Hashtable;import org.exolab.castor.xml.Marshaller;public class Object2XML {public static void main(String[] args) {Model model = new Model();model.setTitle("Master MOdel");model.setNum(99);model.setSort(10);model.setList(new ArrayList<SubModel>());model.setTable(new Hashtable<String,SubModel>());//加入兩組SubModel到ListSubModel subModel1 = new SubModel();subModel1.setName("Sub Model 1");model.getList().add(subModel1);SubModel subModel2 = new SubModel();subModel2.setName("Sub Model 2");model.getList().add(subModel2);//加入SubModel到HashTableSubModel subModel3 = new SubModel();subModel3.setName("Sub Model 3");model.getTable().put("Sub Model 3", subModel3);//轉換為XMLStringWriter stringWriter = new StringWriter();try {Marshaller.marshal(model, stringWriter);} catch (Exception e) {e.printStackTrace();}//顯示XMLSystem.out.println(stringWriter.toString());}} - Unmarshal 轉換程式 XML2Object.java
12345678910111213141516171819202122232425262728293031323334import java.io.StringReader;import java.util.Enumeration;import org.exolab.castor.xml.Unmarshaller;public class XML2Object {public static void main(String[] args) {String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><model num=\"99\"><sort>10</sort><table xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:java=\"http://java.sun.com\" xsi:type=\"java:org.exolab.castor.mapping.MapItem\"><key xsi:type=\"java:java.lang.String\">Sub Model 3</key><value xsi:type=\"java:SubModel\"><name>Sub Model 3</name></value></table><list xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:java=\"http://java.sun.com\" xsi:type=\"java:SubModel\"><name>Sub Model 1</name></list><list xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:java=\"http://java.sun.com\" xsi:type=\"java:SubModel\"><name>Sub Model 2</name></list><title>Master MOdel</title></model>";//轉換JavaBeanModel model = null;try {StringReader stringReader = new StringReader(xml);model = (Model)Unmarshaller.unmarshal(Model.class, stringReader);} catch (Exception e) {e.printStackTrace();}//顯示內容System.out.println("Title:"+model.getTitle());System.out.println("Num:"+model.getNum());System.out.println("Sort:"+model.getSort());for (SubModel subModel : model.getList()) {System.out.println("[List] SubModel Name:"+subModel.getName());}Enumeration<SubModel> enumeration = model.getTable().elements();while( enumeration.hasMoreElements() ){SubModel subModel = enumeration.nextElement();System.out.println("[Table] SubModel Name:"+subModel.getName());}}}
執行結果
- Object2XML.java
1< ?xml version="1.0" encoding="UTF-8" ?> - XML2Object.java
12345678log4j:WARN No appenders could be found for logger (org.castor.core.util.AbstractProperties).log4j:WARN Please initialize the log4j system properly.Title:Master MOdelNum:99Sort:10[List] SubModel Name:Sub Model 1[List] SubModel Name:Sub Model 2[Table] SubModel Name:Sub Model 3
結論
Castor 在使用上確實比 JAXB 來的簡易,假如搭配 Java Class Loader 更能夠發揮自動化的功用,在 OXM 扮演了很重要的角色,也符合 XDNA Framework 精簡快速的精神。