在企業級應用與 Web Services 整合中,Java 物件與 XML 文檔的頻繁轉換是常態。手工編寫解析/序列化代碼不僅繁瑣易錯,還會將業務邏輯與數據綁定細節耦合。本文展示一個基於 JOX (Java Objects in XML) 庫的 BeanXMLMapping 組件,讓 JavaBeans 自行掌控 XML 序列化與反序列化,開發者無需直接操作 SAX、DOM、XSLT 等底層 API。
該組件提供兩個靜態方法:
toXML(Object bean):將任意 JavaBean 實例序列化為 XML 字串。fromXML(String xml, Class clazz):將 XML 字串反序列化為指定類型的 Bean 實例。public class BeanXMLMapping {
public static Object fromXML(String XML, Class className) {
ByteArrayInputStream in = new ByteArrayInputStream(XML.getBytes());
JOXBeanInputStream joxIn = new JOXBeanInputStream(in);
try {
return joxIn.readObject(className);
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
closeQuietly(in, joxIn);
}
}
public static String toXML(Object bean) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
JOXBeanOutputStream joxOut = new JOXBeanOutputStream(out);
try {
joxOut.writeObject(beanName(bean), bean);
return out.toString();
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
closeQuietly(out, joxOut);
}
}
private static String beanName(Object bean) {
String simple = bean.getClass().getSimpleName();
return Character.toLowerCase(simple.charAt(0)) + simple.substring(1);
}
// 輔助關閉方法省略...
}
讓 Bean 自己負責轉換,符合「封裝」原則:
public class AccountHistoryContext {
private String dateFrom;
// 其他屬性、getter/setter 省略...
public String toXML() {
return BeanXMLMapping.toXML(this);
}
public static AccountHistoryContext fromXML(String xml) {
return (AccountHistoryContext) BeanXMLMapping.fromXML(xml, AccountHistoryContext.class);
}
}
| Java 元素 | XML 表示 |
|---|---|
| 類名 | 根元素標籤(首字母小寫) |
| 基本類型屬性 (String, int 等) | 同名子元素,文本內容為值 |
| 嵌套 Bean 屬性 | 嵌套子元素,遞歸映射 |
| 集合/陣列 | 多個同名子元素 |
請求 XML(列表 4):封裝查詢條件(帳號、日期範圍)。
回應 XML(列表 3):包含多筆交易明細(存入/提款、日期、描述、餘額)及帳戶基本資訊。
時序圖(圖 6)展示:前端 → AccountHistoryContext.fromXML() → BeanXMLMapping → JOX 解析 → 領域物件 → 顯示邏輯。
透過 BeanXMLMapping 這類薄封裝層,JavaBeans 能「自己說 XML」,極大降低 XML 集成成本。對於輕量級專案或遺留系統改造,這是比重型綁定框架更務實的選擇。