环境:
commons-betwixt-0.8.jar和commons-digester-2.1.jar(这个地方digester的jar包可以是1.8版本,但千万不能是3.0版本的)
java-version-5.0
commons-betwixt对带有集合javabean转换的约定:
1、[color=blue]集合属性的名字要以集合元素类的名字开头(大小写不敏感)[/color];
2、[color=blue]每个Bean都必须有一个不带参数的构造方法。或者bean不要写任何构造方法(这样实际上有一个默认的不带参数的构造方法)[/color]。
3、[color=blue]每个对于包含其他Bean集合的Bean,要有一个addXxxBean(XxxBean bean)的方法,只有这样,才能保证将xml转换为java的时候,集合属性不丢失[/color]。
例子:一个人Person可以有多个宠物Pet,现在创建一个Person,将其转换为XML,然后做个逆转。
Pet.java代码:
import java.io.Serializable;
public class Pet implements Serializable {
private String nikename; //昵称
private String color; //颜色
/**
* 这个默认的构造方法不可少
*/
public Pet() {
}
public Pet(String nikename, String color) {
this.nikename = nikename;
this.color = color;
}
public String getNikename() {
return nikename;
}
public void setNikename(String nikename) {
this.nikename = nikename;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String toString() {
return "Pet{" + "nikename='" + nikename + '\'' + ", color='" + color + '\'' + '}';
}
}
Person.java代码:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Person implements Serializable {
private String name; //姓名
private int age; //年龄
private List<Pet> petList; //拥有的宠物
/**
* 这个默认的构造方法不可少,否则转换出错
*/
public Person() {
petList = new ArrayList<Pet>();
}
public Person(String name, int age) {
petList = new ArrayList<Pet>();
this.name = name;
this.age = age;
}
//------------add集合成员的方法-----------
/**
* 添加集合属性元素的方法,add后的单词必须决定了xml中元素的名字
* @param pet
*/
public void addPet(Pet pet) {
petList.add(pet);
}
//------------getter/setter-----------
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Pet> getPetList() {
return petList;
}
public void setPetList(List<Pet> petList) {
this.petList = petList;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Person{" + "name='" + name + '\'' + ", age=" + age + ", petList=\n");
for (Pet pet : petList) {
sb.append("\t\t" + pet.toString()).append(";\n");
}
sb.append('}');
return sb.toString();
}
}
TestBetwixt.java代码:
import java.beans.IntrospectionException;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import org.apache.commons.betwixt.io.BeanReader;
import org.apache.commons.betwixt.io.BeanWriter;
import org.xml.sax.SAXException;
import com.commonsbetwixt.dto.Person;
import com.commonsbetwixt.dto.Pet;
public class TestBetwixt {
public static String java2XML() throws IOException, SAXException, IntrospectionException {
String reslutXml;
// 创建一个输出流,将用来输出Java转换的XML文件
StringWriter outputWriter = new StringWriter();
// 输出XML的文件头
outputWriter.write("<?xml version='1.0' ?>\n");
// 创建一个BeanWriter实例,并将BeanWriter的输出重定向到指定的输出流
BeanWriter beanWriter = new BeanWriter(outputWriter);
// 配置BeanWriter对象
beanWriter.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
beanWriter.getBindingConfiguration().setMapIDs(false); // 不自动生成ID
beanWriter.setWriteEmptyElements(true); // 输出空元素
beanWriter.enablePrettyPrint(); // 格式化输出
// 构建要转换的对象
Person person = new Person("唐伯虎", 24);
Pet pet1 = new Pet("旺财", "黄色");
Pet pet2 = new Pet("小强", "灰色");
person.getPetList().add(pet1);
person.getPetList().add(pet2);
// 将对象转换为XML
beanWriter.write(person);
// 获取转换后的结果
reslutXml = outputWriter.toString();
// 关闭输出流
outputWriter.close();
return reslutXml;
}
public static Person xml2Java(String xml) throws IntrospectionException, IOException, SAXException {
// 创建一个读取xml文件的流
StringReader xmlReader = new StringReader(xml);
// 创建一个BeanReader实例,相当于转换器
BeanReader beanReader = new BeanReader();
// 配置BeanReader实例
beanReader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
beanReader.getBindingConfiguration().setMapIDs(false); // 不自动生成ID
// 注册要转换对象的类,并指定根节点名称
beanReader.registerBeanClass("Person", Person.class);
// 将XML解析Java Object
Person person = (Person) beanReader.parse(xmlReader);
return person;
}
/**
* @param args
*/
public static void main(String[] args) {
try {
String xml = java2XML();
System.out.println(xml);
Person person = xml2Java(xml);
System.out.println(person);
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
}
运行结果:
log4j:WARN No appenders could be found for logger (org.apache.commons.betwixt.io.AbstractBeanWriter).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
<?xml version='1.0' ?>
<Person>
<age>24</age>
<name>唐伯虎</name>
<petList>
<pet>
<color>黄色</color>
<nikename>旺财</nikename>
</pet>
<pet>
<color>灰色</color>
<nikename>小强</nikename>
</pet>
</petList>
</Person>
Person{name='唐伯虎', age=24, petList=
Pet{nikename='旺财', color='黄色'};
Pet{nikename='小强', color='灰色'};
}
看到了吧,双向转换成功了。
但是修改下petList属性的名字,修改下getPetList、setPetList的名字,去掉默认的构造方法,使得不符合上面的约定原则,双向转换就失败了。
另外,经过commons-betwixt还有一个问题,就是在将xml转Java过程中,如果日期数据元素为空,则导致转换失败。解决办法是,将java转xml的时候,设置忽略空元素beanWriter.setWriteEmptyElements([color=red]false[/color]);,在将xml转java 的时候,空日期元素删除掉即可。