Apache Commons Betwixt2 的陷阱
环境:
Betwixt2 0.8
Java5
Apache Commons Betwixt2 真是个变态的家伙,当你用Betwixt2在java与xml之间做转换的时候,如果Bean中有集合属性,就千万要注意了。----如果你搞不好,在xml转向java的时候,集合属性就丢失了。
追其原因,是Betwixt2对带有集合的javabean转换有些约定:
1、集合属性的名字要以集合元素类的名字开头(大小写不敏感);
2、每个Bean都必须有一个不带参数的构造方法。或者bean不要写任何构造方法(这样实际上有一个默认的不带参数的构造方法)。
3、每个对于包含其他Bean集合的Bean,要有一个addXxxBean(XxxBean bean)的方法,只有这样,才能保证将xml转换为java的时候,集合属性不丢失。
由于这个原因,我差点将原来费了好大劲写好的代码推翻重做了。现在写个简单的例子放出来,希望对遇到同样问题的博友有所帮助。下面看个例子吧:
例子是这样的:一个人Person可以有多个宠物Pet,现在创建一个Person,将其转换为XML,然后做个逆转。实现代码如下:
package bt;
import java.util.ArrayList;
import java.util.List;
/**
* 人
*
* @author leizhimin 2008-10-22 10:16:06
*/
public class Person {
private String name; //姓名
private int age; //年龄
private List petList; //拥有的宠物
//------------constructor-----------
/**
* 这个默认的构造方法不可少,否则转换出错
*/
public Person() {
petList = new ArrayList();
}
public Person(String name, int age) {
petList = new ArrayList();
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 getPetList() {
return petList;
}
public void setPetList(List 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();
}
}
package bt;
/**
* 宠物
*
* @author leizhimin 2008-10-22 10:17:03
*/
public class Pet {
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 + '\'' +
'}';
}
}
package bt;
import org.apache.commons.betwixt.io.BeanReader;
import org.apache.commons.betwixt.io.BeanWriter;
import org.xml.sax.SAXException;
import java.beans.IntrospectionException;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
/**
* 超变态的Betwixt测试
*
* @author leizhimin 2008-10-22 11:28:15
*/
public class TestBetwixt {
public static void main(String[] args) throws IOException, SAXException, IntrospectionException {
String xml = java2XML();
System.out.println(xml);
Person person = xml2Java(xml);
System.out.println(person);
}
public static String java2XML() throws IOException, SAXException, IntrospectionException {
String reslutXml;
//创建一个输出流,将用来输出Java转换的XML文件
StringWriter outputWriter = new StringWriter();
//输出XML的文件头
outputWriter.write("\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;
}
}
运行结果:
log4j:WARN No appenders could be found for logger (org.apache.commons.betwixt.io.AbstractBeanWriter).
log4j:WARN Please initialize the log4j system properly.
24
唐伯虎
黄色
旺财
灰色
小强
Person{name='唐伯虎', age=24, petList=
Pet{nikename='旺财', color='黄色'};
Pet{nikename='小强', color='灰色'};
}
Process finished with exit code 0
看到了吧,双向转换成功了。
但是修改下petList属性的名字,修改下getPetList、setPetList的名字,去掉默认的构造方法,使得不符合上面的约定原则,双向转换就失败了。
另外,经过Betwixt2还有一个陷阱,就是在将xml转Java过程中,如果日期数据元素为空,则导致转换失败。解决办法是,将java转xml的时候,设置忽略空元素beanWriter.setWriteEmptyElements(false );,在将xml转java 的时候,空日期元素删除掉即可。
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com