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<User> 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<User> done = new RpcCallback<User>() { 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

<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>protobuf</display-name> <servlet> <servlet-name>UserServiceServlet</servlet-name> <servlet-class>servlet.UserServiceServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>UserServiceServlet</servlet-name> <url-pattern>/UserService</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>  

 

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<Message> 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<mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js"></mce:script><mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js"></mce:script>.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<User> done = new RpcCallback<User>() { 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); } }  

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