cmt的项目背景:
cmt的实现原理:
cmt的基本开发过程:
搞java已经3年了,感觉java的应用场景主要还是局限在b/s程序上面,因为用java来做C/S程序不仅比较麻烦,而且运行速度还很慢,与操作系统的界面外观格格不入。eclipse的swt运行速度比swing快得多,但是蹩脚的线程封装和繁琐的控件调用,让swt的界面开发工作变得非常的麻烦。
因为工作的原因接触flex已经快一年了,虽然他的语法跟java比较起来不是那么的完美,但是每种语言都有它的长处,flex也不例外,用它来做界面开发,不仅开发速度快,界面美观,运行速度也很快,而且和与其他系统的整合也相当方便,毕竟flex编译出来的swf可以用flash activeX来播放,可以与任何支持activeX容器的平台集成。
由于上面的原因,有了将flex与java平台集成于一体互相取长补短的想法,实现方便的互相调用,就像调用本地方法一样。当前基于
web service的flex库,可以让flex调用web service,实现对其他平台的调用,但是这种调用只是单向的,服务方不能调用flex,而且作为C/S程序分发和配置也相当繁琐。
flex调用java:
将flex的本地对象串行化为对应的XML字符串,然后将此字符串通过套接字发送给java。java接收到字符串后解析此字符串,通过反射机制,将此字符串转换为对应的java对象,最后调用对应的方法。
java调用flex:
与flex调用java类似
好了废话不多说了,让我们来看看基本的开发步骤吧:)
java方面:
1:打开eclipse新建一java项目
2:导入cmt.jar和dom4j.jar两个需要的库
flex方面:
新建一web application 将cmt.swc库导入到此项目中
图一:
图二:
flex调用java:
1:在java项目中新建test.IvkTest类,作为服务类,具体代码如下:
public class IvkTest {
public String hello(String input){
System.out.println(input);
return "java的返回";
}
public static void main(String[] args) {
ChannelFactory.init();
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
稍后flex会调用此类的hello方法,并传入相应的参数,同时此方法会返回一字符串,被flex显示出来。
main方法在开始调用ChannelFactory类的静态init方法,打开数据访问通道,java与flex之间的数据传输就是通过此通道进行的。
后面的while循环,阻止主线程的退出。
2:在flex项目中新建test包,与java的IvkTest类所在的包对应
3:在该包中新建IvkTest类(此类是java方IvkTest类的代理类,调用此类的方法时,它会去调用java的对应方法完成特定的功能,这种类在真正的项目中很多)
该类的具体代码如下:
package test
{
import org.communicator.DataChannelFactory;
import org.communicator.server.BaseIvkServer;
public class IvkTest extends BaseIvkServer //所有的代理类都继承自BaseIvkServer类,它封装了具体的调用细节
{
public static var INSTANCE:IvkTest=new IvkTest();//为了模拟单列模式,所以在此创建了该类的静态字段
public function IvkTest()
{
}
/*
此方法就是一个简单的代理方法,此方法被调用时,它会自动的去调用java的test.IvkTest类的hello方法,并按程序将args数组中的
每个元素,做为hello方法的参数传入。java返回后,作为回调函数的resFun会被自动调用完成相应的功能。
DataChannelFactory.DEFAULT_URL为数据通道的地址,这里取默认。
args 为调用java方法时传入的参数,顺序与args数组中的顺序一致。
*/
public function hello(str:String,resFun:Function):String{
var args:Array=[str];
this.sendRequest(DataChannelFactory.DEFAULT_URL,"hello",args,resFun);
return null;
}
}
}
2:在flex项目中新建CmtTest.mxml Application 文件具体代码如下:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:initialize>
<![CDATA[
DataChannelFactory.CREATE_CHANNELS([new ChannelUrl("127.0.0.1",1236)]);
]]>
</mx:initialize>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import test.IvkTest;
import org.communicator.ChannelUrl;
import org.communicator.DataChannelFactory;
function onClick():void{
IvkTest.INSTANCE.hello("hello 我是flex",function ret(res:String):void{//ret方法的参数类型与test方法的返回类型相同
Alert.show(res);
});
}
]]>
</mx:Script>
<mx:Button label="ivkTest" click="onClick()"/>
</mx:Application>
首先在我们在Application初始化的时候调用DataChannelFactory.CREATE_CHANNELS([new ChannelUrl("127.0.0.1",1236)]);
连接上java方的数据通道。当按钮被点击后,onClick()方法会调用IvkTest类的hello方法,当java返回后,简单的Alert出java的返回。
java调用flex:
这是最精彩的利用同一个数据通道,可以实现java与flex的互调,使java+flex做C/S程序成为可能。
1:首先在flex的test包下新建服务类型IvkFlex,让java调用,具体代码如下:
package test
{
import mx.controls.Alert;
public class IvkFlex
{
public function IvkFlex()
{
}
public function test(str:String):String{//稍后java会调用此方法,很简单不用多说。
Alert.show(str);
return 'flex的返回';
}
}
}
2:在java中创建对应的代理类型(包名与类名称相同),代码如下:
package test;
import org.communicator.protocol.ChannelFactory;
import org.communicator.protocol.ClientTask;
import org.communicator.server.BaseIvkServer;
public class IvkFlex extends BaseIvkServer {//与flex的代理类类型,也要继承BaseIvkServer 类,实现方便的调用flex服务
public IvkFlex() {
}
//代理方法,与flex的服务方法对应,名称相同
public String test(String info){
Object[] params=new Object[]{info};//调用flex方法时的输入参数
ClientTask clientTask=this.sendMiddVal(ChannelFactory.DEFAULT_PORT, "test", params);
return clientTask.retVal.toString();//ClientTask 类型为此此调用的任务对象,cmt会将此次调用的返回信息设置到它的retVal属性中
}
/**
* @param args
*/
public static void main(String[] args) {
org.communicator.protocol.ChannelFactory.init();//打开数据通道
String ret=new IvkFlex().test("flex你好我是java");//调用flex
System.out.println(ret);//打印flex的返回信息
while(true){//挂起主线程,防止线程的退出
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}