功能说明
提供了将 beans 转换成 XML 的方法
需要的包
commons-collections-3.2.jar
commons-logging-1.0.4.jar
commons-beanutils-1.8.0-BETA.jar
说明
betwixt也可以将xml转化成为bean,功能上和commons-digester相同,实际上它也只是对commons-digester进行了一个包装和扩展,因此如果需要"xml转化成为bean",则需要commons-digester-1.8.jar,这个jar放到not nessary文件夹下
实例一(example1)
实现功能
把下面这个java类转化成为xml文件
转化结果形为:
代码部分:
<?xml version='1.0' encoding='GB2312' ?>
<最外层包装>
<一个BeanJava对象 这个配置文件中定义的值="1.0" String类型对象="aaa">
<int类型对象>12</int类型对象>
<ArrayList类型对象>
<ArrayList中的值>al1</ArrayList中的值>
<ArrayList中的值>al2</ArrayList中的值>
</ArrayList类型对象>
<Map类型对象>
<Map中的值>
<key>key2</key>
<value>value2</value>
</Map中的值>
<Map中的值>
<key>key1</key>
<value>value1</value>
</Map中的值>
</Map类型对象>
</一个BeanJava对象>
</最外层包装>
//定义一个Writer
StringWriter outputWriter = new StringWriter();
outputWriter.write(" /n");//xml的头
outputWriter.write("<最外层包装>/n");//
//定义一个BeanWriter
BeanWriter beanWriter = new BeanWriter(outputWriter);
/****************下面是一些属性设定项,都不是必须的**********************/
//是否禁止id属性(id属性是betwixt自动添加的)
beanWriter.getBindingConfiguration().setMapIDs(false);
// 当遇到ArrayList或者Map时做一个包装
beanWriter.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
//是否以attribute的形式显示简单的id
beanWriter.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
//每行结束时用什么字符,这里用一个换行符
beanWriter.setEndOfLine("/n");
//是否以缩进方式显示
beanWriter.enablePrettyPrint();
//如果是null就写一个空值
beanWriter.setWriteEmptyElements(false);
/*********************属性设定项完毕*********************************/
ArrayList al=new ArrayList();
al.add("al1");
al.add("al2");
Map map=new HashMap();
map.put("key1", "value1");
map.put("key2", "value2");
//定义BeanJava
BeanJava bj1=new BeanJava("aaa",12,al,map);
// beanWriter.write("bjg", bj1);//javabean转化成为了XML,这个方法自定义顶层元素名字
beanWriter.write(bj1);//javabean转化成为了XML,用默认的
outputWriter.write("最外层包装>");
说明:
-
这个目录下有个BeanJava.betwixt文件,定义了xml文件的显示方式, 文件命名必须和类文件BeanJava同名.
-
这个文件不是必须的,如果没有,则显示成下面的形式
<BeanJava>
<a_s>aaa</a_s>
<b_i>12</b_i>
<c_al>
<String>al1</String>
<String>al2</String>
</c_al>
<d_map>
<entry>
<key>key2</key>
<value>value2</value>
</entry>
<entry>
<key>key1</key>
<value>value1</value>
</entry>
</d_map>
</BeanJava>
可以看到,它是按照属性名来定义根节点的
3 BeanJava.betwixt文件
<info primitiveTypes="attribute">
<element name='一个BeanJava对象'>
<attribute name='这个配置文件中定义的值' value='1.0'/>
<attribute name='String类型对象' property='a_s'/>
<element name='int类型对象' property='b_i'>
</element>
<element name='ArrayList类型对象'>
<element name='ArrayList中的值' property='c_al'/>
</element>
<element name='Map类型对象'>
<element name='Map中的值' property='d_map'>
</element>
</element>
</element>
</info>
实例二(example2)
功能
实例一实现了一个普通的javabean的映射,在实际开发中,会碰到一个类中的属性是另一个自定义类的情况,实际上过程是一样的.
把father转化为形如如下的xml:
代码
* <?xml version='1.0' encoding='GB2312' ?>
<父亲>
<姓名>GG</姓名>
<孩子>
<性别>male</性别>
<年龄>12</年龄>
<成绩>100</成绩>
</孩子>
</父亲>
Child c=new Child("male",12,"100");
Father f=new Father("GG",c);
StringWriter outputWriter = new StringWriter();
outputWriter.write(" /n");//xml的头
BeanWriter beanWriter = new BeanWriter(outputWriter);
/*********下面是一些属性设定项,都不是必须的**********************/
//是否禁止id属性(id属性是betwixt自动添加的)
beanWriter.getBindingConfiguration().setMapIDs(false);
//每行结束时用什么字符,这里用一个换行符
beanWriter.setEndOfLine("/n");
//是否以缩进方式显示
beanWriter.enablePrettyPrint();
/**********属性设定项完毕******************************/
beanWriter.write(f);//javabean转化成为了XML,用默认的
三betwixt 问题
在实际应用中,会有先xml配置文件,后javabean映射的情况。举个例子
<xx>
<parameter name="key1">value1</parameter>
<parameter name="key2">value2</parameter>
<parameter name="key3">value3</parameter>
<parameter name="key4">value4</parameter>
</xx>
上面的value1是从map取出来的。如果我们用betwixt,最后生成的只会是
<entry>
<key>key2</key>
<value>value2</value>
</entry>
。要想达到value4的效果,唯一变通方法是建立一个
class MapBeanInn {
public Object keyBetwixt;
public Object valueBetwixt;
……省略setter/getter方法
}
这样做坏处是:增加代码混乱度,降低维护性;破坏了xml-javabean映射的javabean pojo封装。Betwixt文档很少,打开Log,直接看源码。
|2009-07-22 11:41:07,349|DEBUG-[Could not find betwixt file HashMap$Entry.betwixt]-[commons.betwixt.XMLIntrospector.findByXMLDescriptor,1270]
看到由于Could not find betwixt file HashMap$Entry.betwixt,因此没有解析HashMap$Entry。
到commons.betwixt.XMLIntrospector.findByXMLDescriptor,1270 看看
protected synchronized XMLBeanInfo findByXMLDescriptor( Class aClass ) {
// trim the package name
String name = aClass.getName();
int idx = name.lastIndexOf( '.' );
if ( idx >= 0 ) {
name = name.substring( idx + 1 );
}
name += ".betwixt";
URL url = aClass.getResource( name );
得到url=null;
可以再后面加段代码试试
/*
* gaoling 添加!
*/
if(url==null)
url=new URL("file:/D:/WorkSpace/eclipseWorks/workspace3/Betwixtt/bin/com/gaoling/test6/"+name);
在src下建立HashMap$Entry.betwixt
解析成功!再前后翻翻代码,会发现betwixt 解析. Betwixt文件时
直接去处理xxx了,不会继续分析你是否有拆分请求,也就是说,如果想通过
<element name='HASHMAP' property=’xxx’>直接去处理xxx了,不会继续分析你是否有拆分请求,也就是说,如果想通过
<element name='HASHMAP' property=’某个hashmap属性’>
<text property='某个hashmap属性.key'/>
<attribute name='name' property='某个hashmap属性.value'/>
</element>
这样的配置来得到<parameter name="key4">value4</parameter>
是不可行的!
Betwixt的硬伤。
换Castor这个大炮可以解决需求。