java与as3,amf交互相互解析vo数据例子

其它参考:http://www.programcreek.com/java-api-examples/index.php?api=flex.messaging.io.amf.Amf3Output

AMF这东西跟服务端交互还是挺爽的,搜了一下,发现网上没有很完整的例子,大多只有一段。今天整理下之前的项目代码,抽出amf来上个教程,怕以后忘记了。本教程写的是http,Servlet交互的方式。socket方式要写粘包,代码麻烦,不写了。

调试环境

1.java jdk 1.6
2.flash builder 4.5
3.blazeDS(下载地址http://opensource.adobe.com/wiki/display/blazeds/Downloads/,最新4.X版本下载好像被墙了,懒得翻的可以从http://opensource.adobe.com/wiki/display/blazeds/download+blazeds+3这里下载旧版本。

知识前提:
1.懂得配置java,eclipse,flex环境
2.懂得socket,Servlet等相关知识


首先先上web开发http方式交互的例子:
1.用eclipse新建一个web项目,名为TestWeb。选j2ee,把blazeDS相关包添入。
2.新建VO,名为TestResult代码如下:(注意串化)

package model;

import java.io.Serializable;

public class TestResult  implements Serializable
{
    private static final long serialVersionUID = 5297328693553539438L;
    private int id;
    private String name;
    private String desc;
    private int[] ls;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public int[] getLs() {
        return ls;
    }
    public void setLs(int[] ls) {
        this.ls = ls;
    }
}


3.新建amf类,名为TestAMF,代码如下:
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.zip.DeflaterOutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.TestResult;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Input;
import flex.messaging.io.amf.Amf3Output;


public class TestAMF  extends HttpServlet { 

    private static final long serialVersionUID = -1079073749217155506L;  
    
    private SerializationContext context = new SerializationContext(); 

    // post接收
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws  
    ServletException, IOException {  
        response.setContentType("application/x-gzip-compressed");
        
        // 这部份是用来解析接收as的vo数据的
        try {
            long sTime = System.currentTimeMillis();
            Amf3Input amt = new Amf3Input(context);
            amt.setInputStream(request.getInputStream());
            TestResult tr = (TestResult) amt.readObject();
            long uTime = System.currentTimeMillis() - sTime;
            System.out.println("接收到客户端消息,"+tr.getName());
            System.out.println(tr+"解析成功,用时"+uTime+"ms");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("解析错误");
        }
        

        // 这部份是用来生成vo发给客房端的
        Amf3Output out = new Amf3Output(context);  
        DeflaterOutputStream stream = new DeflaterOutputStream(new DataOutputStream(response.getOutputStream()));  
        out.setOutputStream(stream);  
        
        int[] ls = {11,22,33};
        
        TestResult tvo = new TestResult();
        tvo.setId(21);
        tvo.setName("Pelephone");
        tvo.setDesc("发消息给客户端\nhttp://cnblogs.com/pelephone");
        tvo.setLs(ls);

        out.writeObject(tvo);
        stream.finish();  
    }  
    
    // get接收
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws  
    ServletException, IOException {  
        doPost(request, response);
    }  
}



4.修改WEB-INF下的web.xml文件,代码如下:

<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name> test </servlet-name> <servlet-class> TestAMF </servlet-class> </servlet> <servlet-mapping> <servlet-name>test</servlet-name> <url-pattern>/TestAMF</url-pattern> </servlet-mapping> </web-app>
复制代码


5.启动web服务端.(一般默认的地址是http://127.0.0.1:8080/TestWeb)

6.用flash builder(flex)新建一个as项目,名为TestAMF.

7.新建VO,名为TestResult,结构跟java端的统一,代码如下:

package model
{ public class TestResult
    { public var id:int; public var name:String; public var desc:String; public var ls:Array;
    }
}


8.主类TestAMF.as代码如下:

package { import flash.display.Sprite; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.net.registerClassAlias; import flash.utils.ByteArray; import flash.utils.getTimer; import model.TestResult; public class TestAMF extends Sprite
    { private var _loader:URLLoader; public function TestAMF() {  
            trace("TestAMF"); // 一定要先串化vo类才能解析此vo  registerClassAlias("model.TestResult",TestResult);
            
            _loader = new URLLoader();  
            _loader.dataFormat = URLLoaderDataFormat.BINARY;  
            _loader.addEventListener(Event.COMPLETE, loaderHandler);  
            _loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loaderHandler);  
            _loader.addEventListener(IOErrorEvent.IO_ERROR, loaderHandler);  
            var request:URLRequest = new URLRequest("http://127.0.0.1:8080/TestWeb/TestAMF");
            
            
            var tvo:TestResult = new TestResult();
            tvo.id = 123123;
            tvo.name = "testtest";
            tvo.desc = "发消息给服务端\n Pelephone";
            tvo.ls = [1,2,222,333,444]; // post二进制数据给服务端  var out:ByteArray = new ByteArray();
            out.writeObject(tvo);
            request.data = out;
            request.method = URLRequestMethod.POST;
            
            _loader.load(request);
        } private function loaderHandler(event:*):void {  
            trace(event.type); switch(event.type) { case Event.COMPLETE: // 接收到的服务端数据  var start:Number=getTimer();   
                    var byte:ByteArray = _loader.data as ByteArray; byte.uncompress();  
                    var obj:TestResult = byte.readObject();  
                    var end:Number=getTimer();   
                    trace("耗时:" + (end - start) + "毫秒");  
                    trace(obj); break;  
            }  
        }  
    }
}

 

9.F11编译as项目即可看到结果了。

 

运行后可以看到,amf解析效率还是相当不错的。我用999个对象数组放进去解析,就10个ms内搞定。不过跟.net有个相同的地方,就是第一次解析慢。启动第一次解析用了几百个毫秒,估计是生成缓存在内存吧。还有一个不足的地方是amf无法解析Vector类型,可能有方法吧,我暂时没找到。相比java,as的泛型对象显得很憋腿…


最后疑惑一下,很多人跟我AMF协议,我就奇怪,网络协议一般就是http,socket,udp。socket是4层传输,http是7层传输。AMF从应用上看只是一种数据格式而已,像xml,json这样,只是通过代码将这些格式进行转换。在百度百科搜到的资料我更加疑惑了,有一句是这样“AMF协议是基于Http协议的.”http是7层协议,那AMF算什么? 而且我写游戏的时候都是用socket+amf的呀,基于http是什么意思呢?
这些概念不知道谁定义的,会用是一回事,不过要通透看来还要有许多学术知识才行。

你可能感兴趣的:(Flex,as3,fms)