commons-betwixt-0.8.jar和commons-digester-2.1.jar(这个地方digester的jar包可以是1.8版本,但千万不能是3.0版本的)
java-version-5.0
commons-betwixt对带有集合javabean转换的约定:
1、 集合属性的名字要以集合元素类的名字开头(大小写不敏感);
2、 每个Bean都必须有一个不带参数的构造方法。或者bean不要写任何构造方法(这样实际上有一个默认的不带参数的构造方法)。
3、 每个对于包含其他Bean集合的Bean,要有一个addXxxBean(XxxBean bean)的方法,只有这样,才能保证将xml转换为java的时候,集合属性不丢失。
例子:一个人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( false);,在将xml转java 的时候,空日期元素删除掉即可。