学习Protobuf的一个小demo
-
需要导入的依赖
<dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java-util --> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java-util</artifactId> <version>3.1.0</version> </dependency>
-
一个Service_new.proto文件
/*
cd .\src\main\resources
.\protoc --java_out=..\..\..\src\main\java Service_new.proto
*/
syntax = "proto2";
option java_package = "com.hexin.protobuf" ;
option java_outer_classname = "ProtoEntityUtil" ;
// 自定义主体定义 start
message EntityFile{ //基本文件载体
required bytes id = 1; //文件唯一标识符,一般采用文件名
optional int64 version = 2; //文件版本号,客户端不关注。由服务端生成处理。
optional bytes value = 3; //文件内容,业务方自定义
}
// 自定义主体定义 end
// 请求体及反馈体定义 start
message UploadRequest{ //上传请求体
repeated EntityFile file=1; //必要属性file.id|file.value
}
message UploadResponse{ //上传反馈体
required int32 code=1; //处理状态码(详见上传接口的返回报文)
optional int64 version=2; //最大版本号
}
message DownloadResponse{ //下载反馈体
required int32 code=1; //处理状态码(详见下载接口的返回报文)
optional int64 version=2; //最大版本号
repeated EntityFile file=3; //必要属性file.id|file.value
}
// 请求体及反馈体定义 end
message EntityFileValue{ //板块内容
optional string ln = 1; //板块长名称,即ln
optional string xn = 2; //选股问句,即xn
optional string context =3; //股票列表,即stocklist
}
message EntityFileId{ //板块id
required int32 sn=1; //板块名称,sn
}
message EntityFileValue_YuanShuJu{ //额外信息存储
optional string sortstr = 1; //多个板块的展示顺序的排序号
}
3.通过命令,以及protoc.exe生成对应的.java文件, 命令大致如下:
//需注意,前面的路径是生成.java文件所在的路径,后面的路径是.proto文件所在的路径
protoc.exe --java_out=src/main/java/ src/main/resources/Service_new.proto
4.编写对应的测试类
import com.google.protobuf.ByteString;
import com.hexin.protobuf.ProtoEntityUtil;
import java.io.*;
import java.util.Base64;
public class TestServiceNew {
/**
* 上传 /序列化
*/
public static void uploadTest(String id,String value) throws IOException {
// 1.构造一个上传请求的Builder
ProtoEntityUtil.UploadRequest.Builder uploadReqBuilder = ProtoEntityUtil.UploadRequest.newBuilder();
// 2.构造一个信息体 EntityFile 的Builder
ProtoEntityUtil.EntityFile.Builder filebuilder = ProtoEntityUtil.EntityFile.newBuilder();
// 3.把id 内容 set进 信息体的fileBuilder
//filebuilder.setId(ByteString.copyFromUtf8(id));
filebuilder.setId(ByteString.copyFrom(id.getBytes()));
//filebuilder.setValue(ByteString.copyFromUtf8(value));
filebuilder.setValue(ByteString.copyFrom(value.getBytes()));
// 4.将EntityFile上传进Builder,可以加多个
uploadReqBuilder.addFile(filebuilder);
// 5.创建上传请求的实体对象
ProtoEntityUtil.UploadRequest uploadRequest = uploadReqBuilder.build();
// 6. 可能需要对内容base64化 Base64.getEncoder().encode(字节数组)
//String upload = Base64.getEncoder().encode(uploadRequest.toByteArray()).toString();
String upload = new String(Base64.getEncoder().encode(uploadRequest.toByteArray()));
//String upload =uploadRequest.toByteArray().toString();
System.out.println("upload :"+ "\n" + upload);
System.out.println("---------------");
// 控制台输出内容
ProtoEntityUtil.EntityFile filebuild = filebuilder.build();
// 解析内容
ByteString value1 = ProtoEntityUtil.EntityFile.parseFrom(filebuild.toByteArray()).getValue();
//解析内容转string并输出
System.out.println(" 内容:"+ value1.toStringUtf8());
/* // 7.上传操作/ 序列化本地
OutputStream filename = new FileOutputStream("D:/testServiceNew.txt");
uploadRequest.writeDelimitedTo(filename);*/
PrintWriter out = new PrintWriter("D:/testServiceNew.txt");
out.write(upload);
out.close();
}
/**
* 下载 /反序列化
*/
public static void downloadTest(String url) throws IOException {
// 1.通过穿进来的url找到对应的文件
url = "D:/testServiceNew.txt";
// 2.序列化
/* ProtoEntityUtil.UploadRequest entityFile = ProtoEntityUtil.UploadRequest.parseFrom(new FileInputStream(url));
System.out.println("entityfile" +"/n" + entityFile.toString());
// 获取内容
System.out.println("内容:"+entityFile.toString());*/
FileReader in = new FileReader(url);
BufferedReader bin = new BufferedReader(in);
StringBuffer sb = new StringBuffer();
String s = "";
while ((s = bin.readLine()) != null) {
sb.append(s);
}
System.out.println("读到的内容为:" + sb.toString());
//ByteString value = ProtoEntityUtil.EntityFile.parseFrom(ByteString.copyFromUtf8(sb.toString())).getValue();
String res = sb.toString();
ProtoEntityUtil.UploadRequest uploadRequest = ProtoEntityUtil.UploadRequest.parseFrom(Base64.getDecoder().decode(res));
System.out.println("内容: " + uploadRequest.getFile(0).getValue().toStringUtf8());
//HttpClient
}
public static void main(String[] args) {
try {
//uploadTest("123","新年快乐");
downloadTest("D:/testServiceNew.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
}