使用java原生url连接传输protobuf
程序员文章站
2022-05-19 18:01:28
...
protobuf已经出来好多年了,原谅我最近才了解到google这个高性能的用于传输的格式。
从各方面来看,它无论从序列化的性能还是从序列化的压缩比都是优于当前各种传输格式的。如json、xml、hessian,java原生的Serializable。具体对比结果参见:http://agapple.iteye.com/blog/859052
网上也看了些资料,并有所了解,看了下,这玩意儿性能上来说真的没什么可说,但初始化和使用的时候感觉不是特别方便。而且网上的例子多数都是序列化过程,没有很多关于演示网络传输的demo,于是自己简单写了一个,将完整的例子摆在这里。
先定义一个Person.proto
option java_package = "com.example.protobuf"; option java_outer_classname = "PersonProbuf"; message Person { required string name = 1; required int32 id = 2; optional string email = 3; repeated PhoneNumber phone = 4; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } }
使用protoc生成对应的PersonProtobuf类
protoc.exe Person.proto --java_out=.
请求客户端代码如下:
PersonProbuf.Person.Builder personRequest = PersonProbuf.Person.newBuilder(); personRequest.setId(1); personRequest.setName("jesse"); personRequest.setEmail("xx@xx.com"); personRequest.addPhone(PersonProbuf.Person.PhoneNumber.newBuilder().setNumber("1234567890").setType(PersonProbuf.Person.PhoneType.HOME)); //使用java原生URL连接代码生成请求并获得返回值打印 URL url = new URL("http://localhost:90/protobuf.jsp"); URLConnection connection = url.openConnection(); connection.setDoOutput(true); personRequest.build().writeTo(connection.getOutputStream()); PersonProbuf.Person personResponse = PersonProbuf.Person.parseFrom(connection.getInputStream()); System.out.println(personResponse.getId()); System.out.println(personResponse.getName()); System.out.println(personResponse.getEmail()); System.out.println(personResponse.getPhone(0)); System.out.println(personResponse.getPhone(1));
服务端protobuf.jsp代码如下:
<%@ page pageEncoding="UTF-8"%> <%@page import="com.example.protobuf.PersonProbuf"%> <% PersonProbuf.Person person = PersonProbuf.Person.parseFrom(request.getInputStream()); System.out.println(person.getId()); System.out.println(person.getName()); System.out.println(person.getEmail()); System.out.println(person.getPhone(0)); PersonProbuf.Person.Builder personBuilder = person.newBuilder(person); personBuilder.setId(2); personBuilder.setName("tiger"); personBuilder.setEmail("yy@yy.com"); personBuilder.addPhone(PersonProbuf.Person.PhoneNumber.newBuilder().setNumber("0987654321").setType(PersonProbuf.Person.PhoneType.HOME)); personBuilder.build().writeTo(response.getOutputStream()); %>
执行客户端代码后,服务端/客户端输出:
------服务端输出------ 1 jesse xx@xx.com number: "1234567890" type: HOME ------客户端输出------ 2 tiger yy@yy.com number: "1234567890" type: HOME number: "0987654321" type: MOBILE
所以protobuf只是一种序列化的格式,并不是传输协议,需要传输的,只要使用输入输出流,就可以做任何保存,传输的操作。
另外百度写了个jprotobuf开源,使用起来挺方便,只要使用注解放在javabean上就可以了
github:https://github.com/jhunters/jprotobuf
不过这个开源工具对集合没有适合的注解,而且也没有说明和其他语言传输的时候,如何保证一致性,所以需要使用的人考虑清楚,需要慎用。
上一篇: CentOS 添加环境变量
下一篇: 互联网思维系列(4)-案例