httpclient +protobuf 实现数据传输
来源:互联网 发布:陶哲轩现状 知乎 编辑:程序博客网 时间:2024/05/20 13:18
最近项目要接入某联盟广告,采用protobuf作为传输协议,以前没弄过,这次刚好使用到了,整理下1.2 解压安装包1.3 进入软件目录1.4 设置编译目录1.5 安装1.6 配置环境变量
1.7 验证
注意content-type 设置为application/octet-stream。
方式二:
一、环境准备:(mac下)
1.1 下载protobuf2.5安装包
- http://pan.baidu.com/s/1o6v4Sae
- tar -zxf protobuf-2.5.0.tar.gz
- cd protobuf-2.5.0
- ./configure --prefix=/User/jack/software/tools/protobuf
- /User/jack/software/tools/protobuf 为自己设定的编译安装目录
- make
- make install
- sudo vi .bash_profile
- export PROTOBUF=/Users/jack/software/tools/protobuf
- export PATH=$PROTOBUF/bin:$PATH
- jack-3:bin jack$ protoc --version
- libprotoc 2.5.0
二、代码编写
2.1 查看.proto文件,只贴出了部分文件内容
- package mobads.apiv5;
- // 本文件描述API接口版本:5.0.0
- // 版本号信息
- message Version {
- optional uint32 major = 1[default = 0]; // 必填!
- optional uint32 minor = 2[default = 0]; // 选填!
- optional uint32 micro = 3[default = 0]; // 选填!
- };
2.2 下载 protobuf-java-2.5.0.jar
- http://download.csdn.net/download/zinc2008/8128155
2.3 生成.java文件
- protoc --java_out=./ baidu_mobads_api_5.0.proto
同样只贴出部分java源文件 ( 注意java文件不要修改哦)
- // Generated by the protocol buffer compiler. DO NOT EDIT!
- // source: baidu_mobads_api_5.0.proto
- package mobads.apiv5;
- public final class BaiduMobadsApi50 {
- private BaiduMobadsApi50() {}
- }
2.4 代码编写,只贴出关键部分
- MobadsRequest adrequest = MobadsRequest.newBuilder().setRequestId(requestId).setAdslot(adslot).build();
- byte[] content = adrequest.toByteArray();
- HttpClient client = new HttpClient();
- PostMethod postMethod = new PostMethod(URL);
- postMethod.addRequestHeader("Content-Type", "application/octet-stream;charset=utf-8");
- postMethod.setRequestEntity(new ByteArrayRequestEntity(content ));
- client.executeMethod(postMethod);
注意content-type 设置为application/octet-stream。
使用protobuf,所有的参数和返回都是对象的形式,这点还是用着比较爽的。
String byte 切换方法
服务端返回字符串
方式一:
- Arrays.toString(personInfo.toByteArray())
方式二:
- toByteString().toStringUtf8()
客户端解析字符串
方式一:
- private static byte[] fromString(String string) {
- String[] strings = string.replace("[", "").replace("]", "").split(", ");
- byte[] result = new byte[strings.length];
- for (int i = 0; i < result.length; i++) {
- result[i] = Byte.parseByte(strings[i]);
- }
- return result;
- }
- XXX.parseFrom(fromString(byteString))
方式二:
- XXX.parseFrom(ByteString.copyFromUtf8(utf8ByteString))
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只是一种序列化的格式,并不是传输协议,需要传输的,只要使用输入输出流,就可以做任何保存,传输的操作。
0 0
- httpclient +protobuf 实现数据传输
- httpclient +protobuf 实现数据传输
- httpclient +protobuf 实现数据传输
- Qt实现网络数据传输 HttpClient
- cocos2dx HttpClient实现rapidjson格式数据传输
- protobuf 高效数据传输
- 使用httpclient实现上传下载(javaWeb系统数据传输http实现)
- 使用httpclient实现上传下载(javaWeb系统数据传输http实现)
- 使用httpclient实现上传下载(javaWeb系统数据传输http实现)
- HttpClient数据传输的编码方式
- HttpClient数据传输的编码方式
- LuaFramework数据传输Protobuf的解析repeated字段
- iOS 基于Socket使用Protobuf进行数据传输
- HttpClient使用HttpGet进行json数据传输
- HttpClient使用HttpGet进行json数据传输
- webService实现数据传输
- NIO实现UDP数据传输
- NIO实现TCP数据传输
- 算法运行时间、logN、NlogN 之间的比较
- SSL与TLS 区别 以及介绍
- Android xml资源文件中@、@android:type、@*、?、@+含义和区别
- Android ImageView与Bitmap相互转换
- C++ 不能通过‘...’传递有不能平凡复制的类型‘const string {aka const class std::basic_string<char>}’
- httpclient +protobuf 实现数据传输
- 学点Php
- hdu 3038 How Many Answers Are Wrong 带权并查集
- 数据结构(十三)串 KMP算法模式匹配
- Java IO: RandomAccessFile
- clojure 宏 配合 reduce 例子
- 洛谷 P1050 循环
- 程序员的日常逗逼
- 简单实用js——可输入可选择可模糊查询的select下拉