今天試了個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 \n
?-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