今天試了個XML和JavaBean轉換的軟件JOX,之前一直有這樣的需求,但比較來比較去還是這個比較簡單實用。我想除非我有WS的需求,否則象JIBX和APACHE 的WS工具對我來說都是重量級的。
先看看輸出結果:
<?xml version="1.0" encoding="ISO-8859-1"?>
<ApproxItem java-class="com.greatwall.csi.np.model.ApproxItem">
<expose java-class="java.lang.Double">0.23</expose>
<list java-class="com.greatwall.csi.np.model.ApproxInfo">
<IDno>bbb</IDno>
<birth java-class="java.lang.Integer">222</birth>
</list>
<map java-class="java.util.HashMap">
<dd java-class="com.greatwall.csi.np.model.ApproxInfo">
<IDno>bbb</IDno>
<birth java-class="java.lang.Integer">222</birth>
</dd>
<ss java-class="com.greatwall.csi.np.model.ApproxInfo">
<IDno>bbb</IDno>
<birth java-class="java.lang.Integer">222</birth>
</ss>
</map>
<month java-class="java.lang.Integer">3923</month>
</ApproxItem>
在看看原來的JavaBean:
package com.greatwall.csi.np.model;
import java.util.ArrayList;
import java.util.HashMap;
public class ApproxItem {
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public double getExpose() {
return expose;
}
public void setExpose(double expose) {
this.expose = expose;
}
public ArrayList getList() {
return list;
}
public HashMap getMap() {
return map;
}
public void setList(ArrayList list) {
this.list = list;
}
public void setMap(HashMap map) {
this.map = map;
}
private int month;
private double expose;
private ArrayList list;
private HashMap map;
}
處理結果是令人滿意的。實現過程如下:
public class JOXUtils {
/**
* Retrieves a bean object for the
* received XML and matching bean class
*/
public static Object fromXML(String xml, Class className) {
ByteArrayInputStream xmlData = new ByteArrayInputStream(xml.getBytes());
JOXBeanInputStream joxIn = new JOXBeanInputStream(xmlData);
try {
return (Object) joxIn.readObject(className);
} catch (IOException exc) {
exc.printStackTrace();
return null;
}
finally {
try {
xmlData.close();
joxIn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Returns an XML document String for the received bean
*/
public static String toXML(Object bean) {
ByteArrayOutputStream xmlData = new ByteArrayOutputStream();
JOXBeanOutputStream joxOut = new JOXBeanOutputStream(xmlData);
try {
joxOut.writeObject(beanName(bean), bean);
return xmlData.toString();
} catch (IOException exc) {
exc.printStackTrace();
return null;
}
finally {
try {
xmlData.close();
joxOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Find out the bean class name
*/
private static String beanName(Object bean) {
String fullClassName = bean.getClass().getName();
String classNameTemp = fullClassName.substring(
fullClassName.lastIndexOf(".") + 1,
fullClassName.length()
);
return classNameTemp.substring(0, 1)
+ classNameTemp.substring(1);
}
public static void main(String[] args) {
ApproxItem approxItem = new ApproxItem();
approxItem.setMonth(3923);
approxItem.setExpose(0.23);
approxItem.setMap(new HashMap());
ApproxInfo approxInfo = new ApproxInfo();
approxInfo.setBirth(111);
approxInfo.setIDno("aaa");
approxItem.getMap().put("ss", approxInfo);
approxInfo.setBirth(222);
approxInfo.setIDno("bbb");
approxItem.getMap().put("dd", approxInfo);
approxItem.setList(new ArrayList(1));
approxItem.getList().add(approxInfo);
System.out.println("JOXUtils.toXML(approxItem)=");
System.out.println(JOXUtils.toXML(approxItem));
}
Wutka Consulting還提供了一個比較有趣的工具,Java2DTD,自從使用JDO做持久層框架,我就一直想找一個這樣的工具,因爲JDO的映射文件並沒有將全部的JavaBean類描述到.jdo文件,所以在編程環境下一直無法獲取所有的實體類和字段的一個描述情況。廢話少說,馬上試一下。運行時需要3個包文件:beantodtd,需要轉換的實體classes,dtdparser。
java -cp beantodtd-1.0;classes;d:/policy38/lib/dtdparser121.jar; BeanToDTD -mixed com.greatwall.csi.bs.model.PersonBase
-mixed參數是指定按JavaBean中的變量名生成屬性,還有些其它的參數,可以控制大小寫和連字符號等。另外由於我用的實體是JDO增強過的class文件,所以classpath還需要加上JDO實現的包。
運行的結果有少少無奈,因爲對於JavaBean中List這樣的容器字段類型,無法讓它識別出對象的類型,只能生成類似<!ELEMENT pension ANY>這樣的描述,如果在一個什麼配置文件中可以設置的話那就更好了。
另外還有一個DTD解析工具,可以解析DTD文件,目前還不知道有什麼其它用途,使用如下方法可以解析後輸出控制檯:
java -classpath d:/policy38/lib/dtdparser121.jar com.wutka.dtd.Tokenize code.dtd
資源:
http://www.wutka.com/download.html