fbpx

JAVA XML API 教學 - OXM 技術 Castor API

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
    private String title;
    private int num;
    private Integer sort;
    private List<SubModel> list;
    private Hashtable<String,SubModel> table;
  •  設計一個SubModel
    private String name;
  • Marshal 轉換程式 Object2XML.java
    import 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到List
            SubModel 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到HashTable
            SubModel subModel3 = new SubModel();
            subModel3.setName("Sub Model 3");
            model.getTable().put("Sub Model 3", subModel3);
    
            //轉換為XML
            StringWriter stringWriter = new StringWriter();
            try {
                Marshaller.marshal(model, stringWriter);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            //顯示XML
            System.out.println(stringWriter.toString());
        }
    
    }
  • Unmarshal 轉換程式 XML2Object.java
    import 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>";
    
            //轉換JavaBean
            Model 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
    < ?xml version="1.0" encoding="UTF-8" ?>
  • XML2Object.java
    log4j:WARN No appenders could be found for logger (org.castor.core.util.AbstractProperties).
    log4j:WARN Please initialize the log4j system properly.
    Title:Master MOdel
    Num:99
    Sort: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 精簡快速的精神。

發佈留言