Protocol Buffers学习小记-基于servlet的http RPC实现

Protocol Buffers没有提供RPC的具体实现。不过,你可以在 http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns 找到一些第三方开发的RPC实现。

 

本文尝试了http RPC的实现,运行在Tomcat的servlet中。需要注意的是,这只是个测试,实现是不完整的,并且代码很不好看,很不好复用。

 

主要参考: http://www.eishay.com/2008/11/protobuf-vs-spring-rpc.html

 

1、定义协议格式

user.proto

package mytest; option java_package = "mytest.protobuf.gen"; option java_outer_classname = "UserProtos"; message User { required string name = 1; required int32 userId = 2; required string loginName = 3; required string password = 4; } message UserId { required int32 userId = 1; } service UserService { rpc getUser (UserId) returns (User); } 

 

2、生成java代码

protoc --java_out=gen user.proto

 

3、服务端代码

3.1 服务的实现

package myserver; import com.google.protobuf.RpcCallback; import com.google.protobuf.RpcController; import mytest.protobuf.gen.UserProtos.User; import mytest.protobuf.gen.UserProtos.UserId; import mytest.protobuf.gen.UserProtos.UserService; public class UserServiceHandler extends UserService { @Override public void getUser(RpcController controller, UserId request, RpcCallback done) { User.Builder user = User.newBuilder(); user.setUserId(100); user.setLoginName("login1"); user.setPassword("pwd1"); user.setName("user1"); done.run(user.build()); } } 

3.2 servlet

package servlet; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import myserver.UserServiceHandler; import mytest.protobuf.gen.UserProtos.User; import mytest.protobuf.gen.UserProtos.UserId; import com.google.protobuf.RpcCallback; public class UserServiceServlet extends HttpServlet { private static final long serialVersionUID = 1L; private UserServiceHandler _handler = new UserServiceHandler(); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter w = response.getWriter(); w.write("This is a protocal buffer service!"); w.close(); } @Override protected void doPost(HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { RpcCallback done = new RpcCallback() { DataOutputStream dos = new DataOutputStream(response.getOutputStream()); public void run(User user) { try { byte[] array = user.toByteArray(); dos.writeInt(array.length); dos.write(array); dos.flush(); } catch (Exception e) { e.printStackTrace(); } } }; DataInputStream dis = new DataInputStream(request.getInputStream()); byte[] array = new byte[dis.readInt()]; dis.readFully(array); UserId req = UserId.parseFrom(array); _handler.getUser(null, req, done); } }  

 

3.3 web.xml

protobuf UserServiceServlet servlet.UserServiceServlet 1 UserServiceServlet /UserService index.html index.htm index.jsp  

 

4、客户端代码

package myclient; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import mytest.protobuf.gen.UserProtos.User; import mytest.protobuf.gen.UserProtos.UserId; import mytest.protobuf.gen.UserProtos.UserService; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; import org.apache.commons.httpclient.methods.PostMethod; import com.google.protobuf.Message; import com.google.protobuf.RpcCallback; import com.google.protobuf.RpcChannel; import com.google.protobuf.RpcController; import com.google.protobuf.Descriptors.MethodDescriptor; public class ClientByHttp { public static void main(String[] args) { final HttpClient client = new HttpClient(); RpcChannel channel = new RpcChannel() { public void callMethod (MethodDescriptor method, RpcController controller, Message request, Message responsePrototype, RpcCallback done) { try { System.out.println("calling"); PostMethod post = new PostMethod("http://localhost:8080/UserService"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); //dos.writeInt(method.getIndex()); byte[] array = request.toByteArray(); dos.writeInt(array.length); dos.write(array); dos.flush(); byte[] toSend = baos.toByteArray(); System.out.println("sending size = " + toSend.length); post.setRequestEntity(new ByteArrayRequestEntity(toSend )); client.executeMethod(post); DataInputStream dis = new DataInputStream(post.getResponseBodyAsStream()); int size = dis.readInt(); array = new byte[size]; dis.readFully(array); done.run(responsePrototype.newBuilderForType().mergeFrom(array).build()); System.out.println("done"); post.releaseConnection(); } catch (IOException e) { e.printStackTrace(); } } }; UserService service = UserService.newStub(channel); UserId.Builder userId = UserId.newBuilder(); userId.setUserId(1); RpcCallback done = new RpcCallback() { public void run (User user) { System.out.println("name=" + user.getName()); System.out.println("loginname=" + user.getLoginName()); System.out.println("password=" + user.getPassword()); } }; service.getUser(null, userId.build(), done); } }  

你可能感兴趣的:(servlet,user,byte,string,service,exception)