您的位置:首页 > 理论基础 > 计算机网络

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

2016-08-22 17:08 429 查看
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

[c-sharp] view
plain copy

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 服务的实现

[java] view
plain copy

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

[java] view
plain copy

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

[xhtml] view
plain copy

<?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、客户端代码

[java] view
plain copy

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);  

          

    }  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: