Flex传ArrayCollection到java中Collection小插曲中的发现
说在前言:在公司搞了半年多的jsp,最近要转向Flex,搞富客户端。
关于Flex优缺点、如何与java通讯本人也是一知半解,刚接触两周左右,没有很深的理解。声明,在帖子中描述的问题,也许根本就不是问题,只是个人了解还甚少的结果,如果是这样,还烦请大家指出。
本文是有这样一个对话引起发的。
A:我勒个去,真是让人郁闷啊!
B:什么个情况?如实道来,让大家开心下。
A:是这样的,我在Flex中的VO中定义了一个ArrayCollection集合,并将该VO与服务器端(java)的DTO绑定,但是DTO无论如何也接收不到这个集合。我抑郁啊。
B:额,这算哪儿门子问题啊。
A:哎。。。
B:也就是说,前端的ArrayCollection,服务器端木有接收到呗。(新手是不是也总遇到啊!)我帮你解决吧。
于是乎就有了下文。
签于前端传值后端接不到的状况,我测试的思路如下:在Flex中创建一个TestVO,里面就放一个ArrayCollection类型的变量,并与java中创建的TestDTO绑定,TestDTO中放置一个List集合接收前端的ArrayCollection。
代码如下:
TestVO:
package net.greatsoft.communication.organization.vo
{
import mx.collections.ArrayCollection;
[Bindable]
[RemoteClass(alias="net.greatsoft.communication.organization.flex.dto.TestDTO")]
public class TestVO
{
public function TestVO()
{
}
public var _tests:ArrayCollection;
public function get tests():ArrayCollection
{
return _tests;
}
public function set tests(value:ArrayCollection):void
{
_tests = value;
}
}
}
TestDTO:
package net.greatsoft.communication.organization.flex.dto;
import java.util.ArrayList;
import java.util.List;
public class TestDTO {
private List<AgencyTreeDTO> trees;
public List<AgencyTreeDTO> getTrees() {
return trees;
}
public void setTrees(List<AgencyTreeDTO> trees) {
this.trees = trees;
}
}
Java的RO中定义一个为前端提供服务的方法,test(TestDTO dto):
public void test(TestDTO dto){
System.out.println(dto.getTests().size() + "-----------------------------");
}
省略一些无用代码。
看mxml中的调用,在页面中放置一个Button,侦听Button的click事件,在事件的回调函数中,构造两个TestVO,并传递给java的TestDTO,在RO中获取到TestDTO,输入它的长度。继续对调用的返回结果添加侦听事件,如果成功则输出:传输成功,失败则输出:失败啦。
代码如下:
1、Button的click事件处理
protected function btnTest_clickHandler(event:MouseEvent):void
{
var testVO:TestVO = new TestVO();
var trees:ArrayCollection = new ArrayCollection();
var tree1:AgencyTreeVO = new AgencyTreeVO();
tree1.id = "1";
tree1.name = "sfdfsdfdsfdffsdfds";
var tree2:AgencyTreeVO = new AgencyTreeVO();
tree2.id = "2";
tree2.name = "sfdfsdfdsfdffsdfds";
trees.addItem(tree1);
trees.addItem(tree2);
testVO.tests = trees;
agencyProxy.test1(testVO).addResultListener(result_handler).addFaultListener(fault_handler);
}
2、成功返回结果处理事件
private function result_handler(envet:ResultEvent):void{
Alert.show(" 传值成功");
}
3、失败处理事件
private function fault_handler(event:FaultEvent):void{
Alert.show("失败啦");
}
其实明眼人一下就能看出接收不到值得原因,但它不是本文的重点。重点是调试这个低级错误时无意中的收获。
1、运行项目,运行结果如下图:
后台无任何反应。不知问题出在哪。也没有输出size,奇了怪了。
2、修改test(TestDTO testDTO)方法,如下:
public void test(TestDTO dto){
try {
System.out.println(dto.getTrees().size() + "-----------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
也就是加上捕获异常。
运行结果如下:
哈哈,传值成功,但是看一眼后台,心灰意冷啊。
java.lang.NullPointerException at
net.greatsoft.communication.organization.flex.OrganizationRO.test(OrganizationRO.java:150)
空指针异常啊,万恶的java的空指针异常啊。
更让我纳闷儿的是,在后台将异常捕获后,Flex中将返回结果视为正常结果,在跟踪了Flex的代码后发现,此处Flex亦是捕获异常,如有异常则跳转到返回结果失败处理回调函数中(fault_handler),如无异常则跳转到返回结果成功回调函数处理。由于时间已经有点晚了,没有一步步去跟踪,将Flex捕获异常的确切位置贴出来,但是它确实是那样处理的。感情去的朋友,可以自己去跟踪下。
这里得出一条经验:在Flex结合java的应用程序中,不要在服务器端也就是java代码中捕获异常,这样会影响前端对结果的处理。
2、既然得知哪里抛出空指针异常,那把它改掉。
其实是在这里:private List<AgencyTreeDTO> trees,好吧,死马当活马医了。new一个List出来。
package net.greatsoft.communication.organization.flex.dto;
import java.util.ArrayList;
import java.util.List;
public class TestDTO {
private List<AgencyTreeDTO> trees = new ArrayList<AgencyTreeDTO>();
public List<AgencyTreeDTO> getTrees() {
return trees;
}
public void setTrees(List<AgencyTreeDTO> trees) {
this.trees = trees;
}
}
继续运行程序。
嘿嘿,传值成功喽,后台打印:0-----------------------------。额,怎么可能,明明ArrayList的size应该是2啊。继续找原因。
在这里其实依然有一条经验:private List<AgencyTreeDTO> trees = new ArrayList<AgencyTreeDTO>(),它依旧会造成灰常隐晦的问题。这里解决了空指针异常问题,但是无论flex传递给java的参数时候传递成功,给Flex的反馈都是成功的反馈,即没有发生异常。感兴趣的朋友可以将java的RO中的捕获异常去掉。结果依旧。
2、好啦,不卖关子了,其实Flex传ArrayCollection,java端接收不到是因为VO中属性名称和DTO中属性名称不一致造成的。细心啊,粗心搞死人啊。
将DTO中trees改为tests。
运行程序。
后台输出:2-----------------------------。
到此Flex传递ArrayCollection到Java成功。废了不少力气。
B一定也看到怎么解决的了吧,赶紧去A那里炫耀一下吧。可别告诉他你废了多少力气啊。哈哈。
总结一下:
1、在Flex与Java结合的应用中,切忌VO与DTO(或者实体)的属性名称要对应,BlazeDS在做Flex转Java类型的反序列化的需要吧,猜测。初学者很可能忽略这一点。
2、在处理结果集回调函数时,Flex是捕获运行时异常,如发生异常则回调函数采用侦听结果集失败是件,否则采用侦听结果集成功事件处理。
1、在Java的DTO(或者实体)中的属性,尽量不要去new,可能会影响侦听结果集成功、失败事件的判定。如:private List<AgencyTreeDTO> trees = new ArrayList<AgencyTreeDTO>()。
时间不早了,头脑有些不太清醒,语言描述可能不清晰,烦请各位见谅。其实有些饿了。。。