实战Ext -> Struts2 -> Spring数据传递与解析
在以Spring为核心的Web应用中,使用Ext作为Web前台,通过Struts2作为数据交换的“跳板”。
?
原本Struts2自身具备的ModelDriven接口,在使用Ext前台后变得已经没有什么大用了。
?
由于有struts2-json-plugin的支持,可以很方便的获取前台的数据。
?
有点像Ext将数据序列化后,再由后台的Java进行反序列化。但是,Ext毕竟只能提供JSON数据,它的本质还只是POST过来的字符串而已。
?
然而借助struts2-json-plugin提供的 Object JSONUtil.deserialize(String) 方法,可以很简单的将 request 中的字符串“反序列化”为Java对象。
?
但是,在实战中发现,由于“反序列化”的时候并没有一个Java类作为“模板”,所以到底“反序列化”出来的对象是什么类型的,完全由JSONUtil.deserialize方法自己决定。而它只能参考唯一的参数——那个大大的JSON字符串来决定。于是 见到形如数字的就生成 Long,有小数点的就是 Double,其他统统 String,见到[ ]就是List,见到{ }就是Map。
?
然而我们Java端的JavaBean中真的是这些类型吗?
?
那个Long可能仅仅是int,或者根本就是个String;
那个List或许是个数组;
那个Map其实是另一个JavaBean。。。
?
但是,JSONUtil真的猜不到呀。
多么希望JSONUtil能够提供一个这样的重载方法:deserialize(String, Class)
但是,它真的没有。
?
于是我在我的框架中,从Struts2的Action入手。给所有的Action类编制一个抽象父类,并在其中实现这样的“智能反序列化”功能。
?
写这段代码时,发现最为麻烦的就是,如果JSONUtil反序列化后得到的对象中的某个属性是集合类型,而我们的JavaBean中,它其实应该是数组或JavaBean时,如何得到集合类型泛型中的类型。
?
举个例子,JSON字符串经JSONUtil处理后,有个属性 stuffs 的类型是List<E>,而按照JavaBean中的定义,这个 stuffs 的类型是个数组 Human[] stuffs ,这个相对简单一些,假设从JavaBean中反射得到各个属性并遍历时,得到的属性类型为propType:
?
?
这里边用到了一个 ClassUtil.isValueType(Class)?方法用来判定给定的类型是为Java的值类型和基本型:
?
ClassUtil.java
?
<colgroup span="1">
<col style="width: 123pt;" span="1" width="164">
<col style="width: 54pt;" span="1" width="72">
<col style="width: 59pt;" span="1" width="78">
<col style="width: 54pt;" span="3" width="72">
<col style="width: 143pt;" span="1" width="191">
<col style="width: 54pt;" span="1" width="72">
<col style="width: 170pt;" span="1" width="226">
<col style="width: 350pt;" span="1" width="466">
</colgroup>
<tbody>
<tr style="height: 21pt;" height="28">
<td style="width: 1115pt; height: 21pt; background-color: transparent;" colspan="10" width="1485" height="28"><span style="">各种JSON2JAVA反序列工具比较</span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">名称</span></td>
<td style="background-color: transparent;"><span style="">反序列</span></td>
<td style="background-color: transparent;"><span style="">Class参数</span></td>
<td style="background-color: transparent;"><span style="">集合类型</span></td>
<td style="background-color: transparent;"><span style="">泛型</span></td>
<td style="background-color: transparent;"><span style="">JavaBean</span></td>
<td style="background-color: transparent;"><span style="">性能</span></td>
<td style="background-color: transparent;"><span style="">作者</span></td>
<td style="background-color: transparent;"><span style="">备注</span></td>
<td style="background-color: transparent;"><span style="">网址</span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">Struts2-json-plugin</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">X</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">X</span></td>
<td style="background-color: transparent;"><span style="">X</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">json-lib</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○麻烦?</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="">X半自动</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="">比Struts插件慢30%</span></td>
<td style="background-color: transparent;"><span style="">国外组织</span></td>
<td style="background-color: transparent;"><span style="">还有xml--json转换功能</span></td>
<td style="background-color: transparent;"><a href="http://json-lib.sourceforge.net/"><span style="font-size: small;"><span style="">http://json-lib.sourceforge.net/<span style="">?</span></span></span></a></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">jackson</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="">国外组织</span></td>
<td style="background-color: transparent;"><span style="">线程安全</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">Nutz.Json</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="">国人个人</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><a href="http://code.google.com/p/nutz/"><span style="">http://code.google.com/p/nutz/</span></a></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">jroi.json</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="">国人个人</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><a href="http://www.iteye.com/topic/587170"><span style="">http://www.iteye.com/topic/587170</span></a></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">JSONEX</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="">国人个人</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><a href="http://johnson-lee.iteye.com/blog/586686"><span style="">http://johnson-lee.iteye.com/blog/586686</span></a></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">JsonTools</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">gson</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">比jackson慢一个数量级</span></td>
<td style="background-color: transparent;"><span style="">Google</span></td>
<td style="background-color: transparent;"><span style="">对field序列化,而非getter</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">xstream</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="font-size: small;"><span style="">stringtree<span style="">?</span></span></span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style="">?</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style="">JSEL JSON</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style="">○</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="">国人个人</span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><a href="http://code.google.com/p/lite/wiki/JSON"><span style="">http://code.google.com/p/lite/wiki/JSON</span></a></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="text-decoration: underline;"><span style=""> </span></span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="text-decoration: underline;"><span style=""> </span></span></td>
</tr>
<tr style="height: 14.25pt;" height="19">
<td style="height: 14.25pt; background-color: transparent;" height="19"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style=""> </span></td>
<td style="background-color: transparent;"><span style="text-decoration: underline;"><span style=""> </span></span></td>
</tr>
</tbody>
</table> 10 楼 llade 2011-01-17 使用struts 2,我就不太想思考json字符串转换为bean的问题,我脑子里只有一个想法:把参数接收,转换为适当类型。要么用ModelDrive,如果有几个Model,则用action成员变量的方式,接收掉所有参数,然后用BeanUtils来copyProperties来做,通常能满足90%的情况,除非某个Model的成员变量重名。至于性能,和持久化的过程消耗的时间相比微不足道。
所以我使用的架构,不提供json反序列化,只能使用json-lib进行有限的转换。至于数组和Collection,我倾向于2者之间不需要区别,在json层面是没什么意义的。