今天试了个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;
}
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));
}
/**
* 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 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