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<Pet> petList;     //拥有的宠物 

         //------------constructor----------- 

         /** 
         * 这个默认的构造方法不可少,否则转换出错 
         */
 
         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(); 
        } 
}
 
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( "<?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; 
        } 
}
 
运行结果:
log4j:WARN No appenders could be found  for logger (org.apache.commons.betwixt.io.AbstractBeanWriter). 
log4j:WARN Please initialize the log4j system properly. 
<?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='灰色'}; 


Process finished with exit code 0
 
看到了吧,双向转换成功了。
 
但是修改下petList属性的名字,修改下getPetList、setPetList的名字,去掉默认的构造方法,使得不符合上面的约定原则,双向转换就失败了。
 
另外,经过Betwixt2还有一个陷阱,就是在将xml转Java过程中,如果日期数据元素为空,则导致转换失败。解决办法是,将java转xml的时候,设置忽略空元素beanWriter.setWriteEmptyElements( false);,在将xml转java 的时候,空日期元素删除掉即可。
 

本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/107349,如需转载请自行联系原作者
相关文章
|
Apache
java.lang.NoClassDefFoundError: org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream
java.lang.NoClassDefFoundError: org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream
544 0
|
Java Apache Maven
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory解决方法
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory解决方法
1334 0
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory解决方法
|
5月前
|
Java 数据库连接 Apache
深入理解Apache Commons Pool2池化技术
深入理解Apache Commons Pool2池化技术
|
6月前
|
算法 Java Apache
Apache Commons
Apache Commons是一个开源项目,提供了一系列的工具和库,用于简化Java开发中的常见任务。
65 1
|
移动开发 前端开发 Java
Spring MVC-09循序渐进之文件上传(基于Apache Commons FileUpload)
Spring MVC-09循序渐进之文件上传(基于Apache Commons FileUpload)
100 0
|
Java 应用服务中间件 Apache
nested exception is java.lang.NoClassDefFoundError: org/apache/commons/lang/exception/NestableRuntim
nested exception is java.lang.NoClassDefFoundError: org/apache/commons/lang/exception/NestableRuntim
360 0
|
Java Apache
java.lang.NoClassDefFoundError:org/apache/commons/logging/LogFactory
java.lang.NoClassDefFoundError:org/apache/commons/logging/LogFactory
103 0
|
存储 Java Apache
java积累——apache commons fileupload 实现文件上传
java积累——apache commons fileupload 实现文件上传
363 0
|
Apache
Apache Commons DbUtils工具使用
Apache Commons DbUtils工具使用
149 0
Apache Commons DbUtils工具使用
|
存储 JSON Java
【小家java】Java实用数据结构Pair、MutablePair、ImmutablePair详解(推荐apache的commons组件提供)
【小家java】Java实用数据结构Pair、MutablePair、ImmutablePair详解(推荐apache的commons组件提供)

推荐镜像

更多