首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

XML 數據綁定系列(四):Marshaller 將 Java 物件序列化為 XML

     編輯:Java 相關知識

數據綁定系列最終篇:實現 Marshaller 將任意 JavaBean 風格物件轉為 XML 文檔。不依賴原始 Schema,透過反射遍歷 getter 產生屬性與巢狀元素,輸出獨立於 Schema 的純淨 XML,支援 OutputStream 靈活寫入。

設計原則:Schema 無關性

  • Unmarshalling 後的物件不保留 Schema 資訊
  • Marshalling 純靠反射讀取 getter,適用於任何符合 JavaBean 慣例的類
  • 優點:物件可序列化為不同 XML 結構、無額外欄位干擾反射、不洩露 Schema 路徑

核心架構

public class Marshaller {
    // 靜態入口
    public static void marshall(Object obj, OutputStream out) throws IOException {
        new Marshaller().writeXMLRepresentation(obj, out);
    }

    // 遞歸構建 JDOM Element
    private Element getXMLRepresentation(Object obj) throws IOException {
        Class clazz = obj.getClass();
        String name = BindingUtils.initialLowercase(clazz.getSimpleName().replace("Impl", ""));
        Element element = new Element(name);

        for (Method m : clazz.getMethods()) {
            if (m.getName().startsWith("get") && !m.getName().equals("getClass")) {
                try {
                    Object value = m.invoke(obj);
                    String prop = BindingUtils.initialLowercase(m.getName().substring(3));
                    if (value.getClass().getName().startsWith("java.lang.")) {
                        element.setAttribute(prop, value.toString()); // 原生型別 → 屬性
                    } else {
                        element.addContent(getXMLRepresentation(value)); // 複雜型別 → 子元素
                    }
                } catch (Exception e) {
                    throw new IOException(e);
                }
            }
        }
        return element;
    }

    // 輸出
    private void writeXMLRepresentation(Object obj, OutputStream out) throws IOException {
        Document doc = new Document(getXMLRepresentation(obj));
        new XMLOutputter("  ", true).output(doc, out); // 2 空格縮排
    }
}

實戰驗證:雙向轉換

public class TestMapper {
    public static void main(String[] args) throws Exception {
        // 1. XML → Java
        Object o = Unmarshaller.unmarshall(new File("xml/example.xml").toURL());
        WebServiceConfiguration cfg = (WebServiceConfiguration) o;

        // 2. Java → XML (輸出到標準輸出)
        Marshaller.marshall(cfg, System.out);
    }
}

輸出對比

<?xml version="1.0" encoding="UTF-8"?>
<webServiceConfiguration name="Unsecured Web Listener" version="1.1">
  <portType protocol="http" number="80" protectedPort="false"/>
  <documentType index="*.html,*.xml" root="/usr/local/enhydra/html" error="error.html"/>
</webServiceConfiguration>

與原始 XML 僅差異於:無 Schema 引用、無命名空間宣告、屬性順序不同 — 語義完全等價。

Web Service 生命週期整合

public class WebService {
    private File configFile;
    private WebServiceConfiguration config;

    public void start() throws IOException {
        config = Unmarshaller.unmarshal(configFile.toURL());
    }

    public void stop() throws IOException {
        Marshaller.marshal(config, new FileOutputStream(configFile));
    }
}

啟動時解組,關閉時封存,業務邏輯零 XML 感知。

JDOM Beta 5 遷移提醒

代碼已適配 JDOM Beta 5 API 變更,建議同步升級依賴。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved