AS3使用thrift的与JHava servlet服务器端通信
##一、基本概念
Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。
Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
###1.数据类型
基本类型: bool:布尔值,true 或 false,对应 Java 的 boolean byte:8 位有符号整数,对应 Java 的 byte i16:16 位有符号整数,对应 Java 的 short i32:32 位有符号整数,对应 Java 的 int i64:64 位有符号整数,对应 Java 的 long double:64 位浮点数,对应 Java 的 double string:utf-8编码的字符串,对应 Java 的 String 结构体类型: struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean 容器类型: list:对应 Java 的 ArrayList set:对应 Java 的 HashSet map:对应 Java 的 HashMap 异常类型: exception:对应 Java 的 Exception 服务类型: service:对应服务的类
###2.服务端编码基本步骤:
实现服务处理接口impl 创建TProcessor 创建TServerTransport 创建TProtocol 创建TServer 启动Server 3.客户端编码基本步骤:
创建Transport 创建TProtocol 基于TTransport和TProtocol创建 Client 调用Client的相应方法 4.数据传输协议
TBinaryProtocol : 二进制格式. TCompactProtocol : 压缩格式 TJSONProtocol : JSON格式 TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析 tips:客户端和服务端的协议要一致
##二、as3与java通信示例
test.thrift namespace java com.xzw.thrift namespace as3 com.xzw.thrift struct User{ 1:i32 userId, 2:string loginName, 3:string password, 4:string name }
exception UserNotFound{
1:string msg //as3中由于message是关键字,所以避免使用message关键字。
}
service UserService{
User getUser(1:string loginName) throws (1:UserNotFound unf),
list<User> getUsers()
} 通过命令生成java代码
thrift –gen java test.thrift
以上命令会生成gen-java的目录拷贝里面的代码到你的项目中。如图com.xzw.thrift就是
工具生成java类。
其中我们需要去实现UserService类中的IFace接口。代码如下: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.xzw.service; |
import com.xzw.thrift.User;
import com.xzw.thrift.UserNotFound;
import com.xzw.thrift.UserService;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.apache.thrift.TException;
/**
*
* @author xzw
*/
public class UserServiceHandler implements UserService.Iface{
public User getUser(String loginName) throws UserNotFound, TException {
if(!"xuzhiwei".equals(loginName)){
UserNotFound e = new UserNotFound("用户无法找到!");
throw e;
}
User user = new User();
user.setUserId(100);
user.setLoginName("xuzhiwei");
user.setPassword("123456");
user.setName("user1");
Logger.getLogger("user=>"+user.toString());
return user;
}
public List<User> getUsers() throws TException {
List<User> list = new ArrayList<User>();
User user = new User();
user.setUserId(100);
user.setLoginName("xuzhiwei");
user.setPassword("123456");
user.setName("user1");
list.add(user);
User user2 = new User();
user2.setUserId(200);
user2.setLoginName("login2");
user2.setPassword("pwd2");
user2.setName("user2");
list.add(user2);
Logger.getLogger("user list=>"+list.toString());
return list;
}
}
编写servlet,servlet需要继承thrift提供的类包TServlet即可,不需要去重写doGet,doPost方法。 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.xzw.service; |
import com.xzw.thrift.UserService;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServlet;
/**
*
* @author xzw
*/
public class UserServlet extends TServlet{
public UserServlet(){
super(new UserService.Processor(new UserServiceHandler()),new TBinaryProtocol.Factory(true, true));
}
}
以上就完成服务器端的编写了。
可以使用junit测试一下: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ |
import com.xzw.thrift.User;
import com.xzw.thrift.UserService;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
import org.junit.*;
/**
*
* @author xzw
*/
public class TestServlet {
@Test
public void test(){
String serveltUrl = "http://localhost:8080/test_thrift/userServlet";
try {
THttpClient thc = new THttpClient(serveltUrl);
TProtocol lopFactory = new TBinaryProtocol(thc);
UserService.Client client = new UserService.Client(lopFactory);
List users = client.getUsers();
System.out.println("-->>"+users.toString());
} catch (TException ex) {
Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Test
public void test2(){
String serveltUrl = "http://localhost:8080/test_thrift/userServlet";
try {
THttpClient thc = new THttpClient(serveltUrl);
TProtocol lopFactory = new TBinaryProtocol(thc);
UserService.Client client = new UserService.Client(lopFactory);
User user = client.getUser("xuzhiwei");
System.out.println("-->"+user.toString());
} catch (TException ex) {
Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
接下来生成as3代码
thrift –gen as3 test.thrift www.it165.net
以上代码会生成gen-as3的目录,拷贝目录下的代码到你的工程中。
编写as3客户端类:
package {
import com.xzw.thrift.User;
import com.xzw.thrift.UserNotFound;
import com.xzw.thrift.UserService;
import com.xzw.thrift.UserServiceImpl;
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.text.TextField;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
public class testthrift extends Sprite
{
private const SERVER_URL:String = "http://localhost:8080/test_thrift/userServlet";
private var textField:TextField;
public function testthrift()
{
init();
connServer();
}
private function init():void
{
textField = new TextField();
textField.width = 300;
textField.height = 500;
textField.autoSize = "left";
addChild(textField);
}
private function connServer():void
{ //实例化URLRequest
var urlRequest:URLRequest = new URLRequest(SERVER_URL);
//实例化THttpClient
var thc:THttpClient = new THttpClient(urlRequest);
var protocol:TProtocol = new TBinaryProtocol(thc);
var usImpl:UserService = new UserServiceImpl(protocol);
usImpl.getUser("xuzhiwei",onError,onUserSuccess);
//usImpl.getUsers(onError,onSuccess);
}
private function onError(e:UserNotFound):void{
trace(e);
}
private function onUserSuccess(user:User):void{
trace("success:");
trace(user);
textField.text = user.toString();
}
private function onSuccess(user:Array):void{
trace(user);
textField.text = user.toString();
}
}
}
写完了,测试结果