1. 原理及流程简介
1.1 commons-betwixt
基本原理
Commons Betwixt这个组件提供了一个XML自省(introspection)机制用来把Java Bean映射成XML信息(.xml文件或符合xml格式的字符串,下同)或者把XML信息映射成Java Bean。
在解析XML信息时采用SAX方式。
核心类,方法及步骤简介
xml信息映射成java bean
org.apache.commons.betwixt.io.BeanReader
要把xml信息映射成 Java Bean,这个类是最核心的类。首先要构造此类的一个对象。然后配置该对象属性,(包括给XML信息是否匹配Attribute或Id等等),下来最重要的一步是给这个对象注册一个BeanClass,即要转化的Java Bean的类名,函数原型为:void registerBeanClass(String path, Class beanClass),其中path为XML信息中要转化的element名。接下来就是最后一步,调用核心方法Object parse(String),这个方法不是BeanReader本身的。而是它继承的org.apache.commons.digester.Digester里面的方法,这里不在叙述。
java bean映射成xml信息
org.apache.commons.betwixt.io.BeanWriter
要把Java Bean 映射成XML信息,此为核心类。同样,首先要构造此类的一个对象,然后配置该对象(包括是否给生成的XML信息设置格式化,Attribute或Id等等),然后调用核心方法write(String name,Object bean)name是即将生成的XML信息的element名,bean为待转化的对象。此方法是BeanWriter自身的方法。
需要的支持环境:
commons-digester.jar,commons-beanutils.jar, commons-codec.jar, commons-lang.jar,dom4j-1.3.jar
以上都是从http://www.open-java.com/a/200911/10142426.shtml 这里参照过来的,下面是我自己写的サンプル:
Test.java
package beanreadertest04;
import java.beans.IntrospectionException;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.betwixt.io.BeanReader;
import org.xml.sax.SAXException;
/**
* 使用betwixt进行xml与java对象之间的互转解析
* <p>
* 导入commons-logging-1.0.4.jar commons-beanutils-1.6.1.jar
* commons-betwixt-0.8.jar commons-collections-2.1.jar commons-digester-1.7.jar
*
* @author tower
*
*/
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
try {
String xmlPath = "D:\\develop\\eclipse\\WorkSpaceYuYuSeiHo\\HaoTest\\src\\beanreadertest03\\IssueTasksObj.xml";
IssueTasksObj issueTasksObj = (IssueTasksObj) xml2Object(xmlPath,"IssueTasksObj", IssueTasksObj.class);
System.out.println(BeanUtils.describe(issueTasksObj));
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 解析xml文件为Object对象
*
* @param xmlPath
* 需解析的xml文件路径
* @param rootElement
* xml文件的根元素
* @param beanClass
* 根元素所对应的bean类
* @return Object
*/
public static Object xml2Object(String xmlPath, String rootElement, Class<IssueTasksObj> beanClass) {
Object o = null;
try {
BeanReader beanReader = new BeanReader();
// 是否以attribute的形式显示简单的id
beanReader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
// 不自动生成id
beanReader.getBindingConfiguration().setMapIDs(false);
// 当遇到ArrayList或者Map时做一个包装
// beanReader.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
// 注册
beanReader.registerBeanClass(rootElement, beanClass);
// 解析xml为object
o = beanReader.parse(new FileInputStream(xmlPath));
} catch (IntrospectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
}
以上代码中 第33行的 "IssueTasksObj" 要与IssueTasksObj.xml中第2行 "<IssueTasksObj>" 里的字母大小写一定要一致
IssueTasksObj.
<?xml version="1.0" encoding="UTF-8"?>
<IssueTasksObj>
<ftpInfo>
<ip>192.168.11.12</ip>
<password>1234</password>
<port>8080</port>
<username>ceshi</username>
</ftpInfo>
<issueTasks>
<issueTask>
<contentcode>111</contentcode>
<starttime>Tue Dec 30 09:24:04 CST 2008</starttime>
<status>0</status>
</issueTask>
<issueTask>
<contentcode>111</contentcode>
<starttime>Tue Dec 30 09:24:04 CST 2008</starttime>
<status>0</status>
</issueTask>
</issueTasks>
<librarys>
<library>new Librarys1</library>
<library>new Librarys2</library>
<library>new Librarys3</library>
<library>new Librarys4</library>
<library>new Librarys5</library>
</librarys>
</IssueTasksObj>
注意:两个add方法(addIssueTask和addLibrary)最后都没有S。(我最初带上S,XML里的值就取不出来!)
IssueTasksObj.java
package beanreadertest04;
import java.util.ArrayList;
import java.util.List;
public class IssueTasksObj {
private FtpInfo ftpInfo;
// 在这里new是防止空指针
private List<IssueTask> issueTasks = new ArrayList<IssueTask>();
private List<String> librarys = new ArrayList<String>();
/**
* 每个Bean都必须有一个不带参数的构造方法。 或者bean不要写任何构造方法(这样实际上有一个默认的不带参数的构造方法)
*/
public IssueTasksObj() {
}
/**
* 每个对于包含其他Bean集合的Bean,要有一个addXxxBean(XxxBean bean)的方法,
* 只有这样,才能保证将xml转换为java的时候,集合属性不丢失。 ※ 方法名最后没有S ※
*
* @param issueTask
*/
public void addIssueTask(IssueTask issueTask) {
issueTasks.add(issueTask);
}
/**
* 每个对于包含其他Bean集合的Bean,要有一个addXxxBean(XxxBean bean)的方法,
* 只有这样,才能保证将xml转换为java的时候,集合属性不丢失。 ※ 方法名最后没有S ※
*
* @param library
*/
public void addLibrary(String library) {
librarys.add(library);
}
public FtpInfo getFtpInfo() {
return ftpInfo;
}
public void setFtpInfo(FtpInfo ftpInfo) {
this.ftpInfo = ftpInfo;
}
public List<IssueTask> getIssueTasks() {
return issueTasks;
}
public void setIssueTasks(List<IssueTask> issueTasks) {
this.issueTasks = issueTasks;
}
public List<String> getLibrarys() {
return librarys;
}
public void setLibrarys(List<String> librarys) {
this.librarys = librarys;
}
}
package beanreadertest04;
public class FtpInfo {
private String ip;
private String username;
private String password;
private int port;
/**
* 每个Bean都必须有一个不带参数的构造方法。 或者bean不要写任何构造方法(这样实际上有一个默认的不带参数的构造方法)
*/
public FtpInfo() {
}
public FtpInfo(String ip, String username, String password, int port) {
this.ip = ip;
this.username = username;
this.password = password;
this.port = port;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
@Override
public String toString() {
return "FtpInfo[" + ip + " " + username + " " + password + " " + port + "]";
}
}
package beanreadertest04;
import java.util.Date;
public class IssueTask {
private int contentcode;
private Date starttime;
private int status;
public IssueTask() {
}
public int getContentcode() {
return contentcode;
}
public void setContentcode(int contentcode) {
this.contentcode = contentcode;
}
public Date getStarttime() {
return starttime;
}
public void setStarttime(Date starttime) {
this.starttime = starttime;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
@Override
public String toString() {
return "IssueTask[" + contentcode + " " + starttime + " " + status + "]";
}
}