这次在编写java版ems的时候,遇到中文接收乱码问题(环境,Python客户端,Java服务端)。刚好对编码问题没什么概念,硬着头皮乱搞一气,无果。当晚请到无线徐工前来帮忙,也是折腾了很久,大概知道是Ice.jar内部编码造成数据无法还原。测试如下:

public static void testZh() throws Exception{
        String str = "中文"; //原字符
        byte[] bys = str.getBytes("gbk");
        String nstr = new String(bys, "utf8"); //被编译字符
        System.out.println(nstr); //????
        byte[] nbys = nstr.getBytes("utf8");
        String rstr = new String(nbys, "gbk");
        System.out.println(rstr); //锟斤拷锟斤拷
    }

      主要问题是在Ice.jar包中默认以UTF8编码,官方讨论区也有国人遇到此问题http://www.zeroc.com/forums/help-center/2878-ice-client-encoding-gbk-error.html,官中人强荐在传输中转码为utf8,我们这么多年的代码积累,岂能说迁就能迁,听国人意见,重新编译Ice.jar包。

    grep -rl UTF ./|xargs replace 'UTF-8' 'ISO-8859-1' --
    grep -rl UTF ./|xargs replace 'UTF8' 'ISO-8859-1' --

      在编译中出现一些不自带的第三方包,但因版本众多,最后还是实验出了合适的版本(下载后把jar包加入到CLASSPATH中即可):

wget http://www.java2s.com/Code/JarDownload/jgoodies/jgoodies-forms-1.4.0.jar.zip
wget http://www.java2s.com/Code/JarDownload/jgoodies/jgoodies-looks-2.2.1.jar.zip

      最后执行 ant -f build.xml就编译成功了。
鸣谢:徐阳

      呵呵,又到了该写文章的时候了,昨天一直想折腾flash js通信,还好最终hello world还是出来了。趁着这两天强大的欲望,所以今天还是决心研究一天,虽然axing没有说不能折腾,但貌似是先做正事的意思,机会难得,我就当他默认了吧 /偷笑。
      昨天,星哥看到ice(www.zeroc.com)发布了flash的ice接口,刚好在这个关口上,怎么能错过呢,赶紧试手,但因为第一次开发,难免被环境花费了很多时间,上午几乎是没做什么事情,而且国内资料几乎没有一点介绍,不得不硬着头皮看官方英文说明,还好还好,认识几个单词,下班前终于小有成就。二期打算弄一个聊天窗口试用,先不谈前景。
      本来这两天在写php框架的,但总是写完一个模块就写不下去了,最终发现缺少架构文档,所以就放下来,打算先出一个框架基本结构说明,这样也可以先跟xing、hait他们讨论一下可实施性和目前公司应用场景,这是我今年的终极KPI,一定要完成。
      好了,到了该贴代码的时间了,哎,文采不好,不会写字,所以到了该贴代码的时候是最高兴的时候了。
      下面这是JS调用flash接口的代码,先上flash脚本代码,没有什么技术含量:

package{
    import flash.text.TextField;
    import flash.display.MovieClip;
    import flash.external.ExternalInterface;
    public class test extends MovieClip{
        public function test(){
            var availTxt:TextField = new TextField();
            availTxt.text = "hahahahahahah";
            addChild(availTxt); //主要是检测flash的确编译成功了
            ExternalInterface.addCallback("hello", hello);
        }
        //js调用的function
        public function hello():String{
            return "hello world";
        }
    }
}

      在做js调用的时候花费了很多时间,js脚本老是提示:找不到该方法,以前用的是flex编辑器生成的,几乎用不了,昨天改用flash css写,很快实现了,但ie正常,firefox还是不行,搜了半天,终于知道ie找的是object元素的name,而firefox找的是embed的name属性,所以就有了下面的奇怪代码:

//创建flash的html代码
function getFlashHtml(src, id, width, height){
    var html = '';
    html += '';
    html += '';
    html += '';
    html += '';
    html += '';
    html += '';
    return html
}
//获取flash句柄
function thisMovie(movieName) {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        return window[movieName+'_ie']; //针对ie
    }else { //针对非ie
        return document[movieName+'_ff'];
    }
}
//等待flash脚本加载完成
function testt(){
    try{
        var te = thisMovie('test');
        var st = te.hello();
        alert(st);
    }catch(e){
        //alert('hah');
        setTimeout('testt()', 500);
    }
}
~function(){
    var f = getFlashHtml('js_flex/test.swf', 'test', 120, 120);
    document.getElementById('test').innerHTML = f;
    testt();
}();

      还算很容易吧,好了,该来点有难度的了,主要是我很不能理解为什么调用了接口后需要使用wenCompleted来异步处理返回的结果呢,难道是因为不想长连接,或者就是flash阻塞很难实现吗,但异步也挺好,跟ajax一样,好,来代码:

package Run{
    import TEST.*; //调用slice2as生成的代码
    import Ice.*;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.external.ExternalInterface;
    import flash.text.TextField;
    public class ice_flash extends MovieClip
    {
        private var _initData:Ice.InitializationData;
        private var _communicator:Ice.Communicator;
        private var _proxy:Object;
        //输出信息到flash
        public function print(str:String):void{
            var availTxt:TextField = new TextField();
            availTxt.width = 500;
            availTxt.height = 300;
            availTxt.text = str;
            addChild(availTxt);
        }
        //创建flash的ice对象
        public function ice_flash(){
            try {
                _initData = new Ice.InitializationData();
                _initData.properties = Ice.Util.createProperties();
                _initData.properties.setProperty("Ice.Warn.Connections", "1");
                _communicator = Ice.Util.initialize(_initData);
                var obj:Ice.ObjectPrx = _communicator.stringToProxy("TestEAS:tcp -h 192.168.0.235 -p 33333 -t 3000");
                _proxy = TEST.EASPrxHelper.uncheckedCast(obj.ice_twoway());
            }catch(e:Error){
                print(e.getStackTrace());
            }
            ExternalInterface.addCallback("invoke", invoke);
            //下面纯属测试代码
            var args:Ice.HashMap = new HashMap();
            args.put("name", "test");
            var res:Ice.HashMap = new HashMap();
            var t:String = invoke("dtest/hello_func", args, res);
            print(t);
        }
        //invoke调用方法,打算释放给js调用
        public function invoke(cmdid:String, args:HashMap, res:HashMap):String{
            var ret:String = '0';
            //print(_proxy.toString());
            try{
                _proxy.invoke(cmdid, args, res).whenCompleted(castComplete, exception);
            }catch(ex:Error){
                ret = ex.toString();
            }
            return ret;
        }
        //调用完成后有结果响应时调用,参数说明:http://doc.zeroc.com/display/AS/ActionScript+Mapping+for+Operations
        private function castComplete(r:Ice.AsyncResult, retval:Number, ret_info:HashMap, ret_list:Vector.):void{
            print(ret_info.find("MSG").toString());
        }
        private function exception(r:Ice.AsyncResult, ex:Ice.Exception):void
        {
            print("eeeeeerorrororororo!");
        }
    }
}

      好吧,至此,flash的ice学习就算是入门了,因为ice对flash的版本还很demo,期待后期完善更多功能。
      鉴于今天把flash折腾的小有成就,犒劳一下自己,买了两张《惊叹号》,送一张给一个刚认识的朋友。《mine mine》和《皮影戏》真的很好听,我工作的动力,加油。