protobuf介绍 就是一种
protobuf简单测试 项目源码见xuanfong1/springLeaning/protobuf
在项目引入maven/gradle依赖compile 'com.google.protobuf:protobuf-java:3.6.1'
下载代码生成工具 ,作用是将file.proto
文件转换成其他语言(java/C++/GO/Python/C#/Dart)的文件,eg:这里选择window平台,版本和maven版本一致,因此选择protoc-3.6.1-win32.zip ,其他操作系统选择对应平台即可,然后解压,在bin目录可以看到protoc.exe
文件,复制重命名protoc-3.6.1-win32.exe
为了好区分版本,其他文件用不着
编写一个测试PersonMsg.proto
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 message Person { required int32 id = 1 ; required string name = 2 ; optional string email = 3 ; repeated string friends = 4 ; }
使用工具进行java代码生成,执行.\protobuf\protoc-3.6.1-win32.exe --java_out=.\protobuf\src\main\java\com\exxk\protobuf\ .\protobuf\src\test\protobuf\PersonMsg.proto
注意,这里生成的代码PersonMsg.java
里面是没有包名的,可以手动加入
在ProtobufApplicationTests.java
编写测试方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.List;public class ProtobufApplicationTests { @Test public void contextLoads () { PersonMsg.Person.Builder personBuilder = PersonMsg.Person.newBuilder(); personBuilder.setId(1 ); personBuilder.setName("叉叉哥" ); personBuilder.setEmail("xxg@163.com" ); personBuilder.addFriends("Friend A" ); personBuilder.addFriends("Friend B" ); PersonMsg.Person xxg = personBuilder.build(); ByteArrayOutputStream output = new ByteArrayOutputStream (); try { xxg.writeTo(output); } catch (IOException e) { e.printStackTrace(); } byte [] byteArray = output.toByteArray(); ByteArrayInputStream input = new ByteArrayInputStream (byteArray); PersonMsg.Person xxg2 = null ; try { xxg2 = PersonMsg.Person.parseFrom(input); } catch (IOException e) { e.printStackTrace(); } System.out.println("ID:" + xxg2.getId()); System.out.println("name:" + xxg2.getName()); System.out.println("email:" + xxg2.getEmail()); System.out.println("friend:" ); List<String> friends = xxg2.getFriendsList(); for (String friend : friends) { System.out.println(friend); } } }
设置自动生成包名,修改PersonMsg.proto
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 syntax = "proto2" ; package PersonMsg;option java_package = "com.exxk.protobuf" ;option java_outer_classname = "PersonMsg" ;message Person { required int32 id = 1 ; required string name = 2 ; optional string email = 3 ; repeated string friends = 4 ; } message car {}
修改命令.\protobuf\protoc-3.6.1-win32.exe --java_out=.\protobuf\src\main\java\ .\protobuf\src\test\protobuf\PersonMsg.proto
protoc gradle插件 插件地址:google/protobuf-gradle-plugin
在父级build.gradle
添加
1 2 3 4 5 6 7 8 buildscript { repositories { mavenCentral() } dependencies { classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.8' } }
在子项目build.gradle
添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 apply plugin: 'com.google.protobuf' dependencies { compile 'com.google.protobuf:protobuf-java:3.6.1' } sourceSets { main { proto { srcDir 'src/main/protobuf' srcDir 'src/main/protocolbuffers' srcDir 'src/main/protocol buffers' include '**/*.protodevel' } } test { proto { srcDir 'src/test/protocolbuffers' } } } protobuf { generatedFilesBaseDir = "$projectDir/src" protoc { artifact = 'com.google.protobuf:protoc:3.0.0' } }
然后点击右侧gradleprotobuf->Tasks->other->generateProto
编译proto文件生成java文件
protoc maven插件 解决不同平台开发编译问题,功能能实现自动根据不同系统(os/win/linux)调用不同的protoc工具
配置更改一直不生效,一直使用最新的3.6.0版本的protoc工具
Maven工程处理Protobuf
目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ├─src │ ├─main │ │ ├─java //proto生成java文件目录 │ │ │ └─com │ │ │ └─surelive │ │ │ └─app │ │ │ └─server │ │ │ └─protocol │ │ │ ├─request │ │ │ └─response │ │ └─resources │ │ └─proto //proto文件目录 │ │ ├─request │ │ └─response │ └─test │ └─java ├─pom.xml
编写pom.xml
添加插件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 <project ... > .... <dependencies > <dependency > <groupId > com.google.protobuf</groupId > <artifactId > protobuf-java</artifactId > <version > 2.5.0</version > </dependency > </dependencies > <build > <defaultGoal > package</defaultGoal > <extensions > <extension > <groupId > kr.motd.maven</groupId > <artifactId > os-maven-plugin</artifactId > <version > 1.6.0</version > </extension > </extensions > <plugins > <plugin > <groupId > org.xolstice.maven.plugins</groupId > <artifactId > protobuf-maven-plugin</artifactId > <version > 0.6.1</version > <extensions > true</extensions > <configuration > <protoSourceRoot > ${project.basedir}/src/main/proto</protoSourceRoot > <outputDirectory > ${project.basedir}/src/main/java</outputDirectory > <clearOutputDirectory > true</clearOutputDirectory > <protocArtifact > com.google.protobuf:protoc:2.5.0:exe:${os.detected.classifier}</protocArtifact > </configuration > <executions > <execution > <goals > <goal > compile</goal > </goals > </execution > </executions > </plugin > </plugins > </build > </project >
使用,点击右侧插件里面的protobuf->protobuf:compile
或者执行mvn protobuf:compile
注意
不添加输出目录识别不了多级目录(奇怪)
设置目录protoSourceRoot
目录是,是以该目录为相对路径,因此代码里面的import "response/xxx.proto
要加上response
二级目录,但是如果可以设置protoSourceRoot为两个或二级目录就不需要修改,clearOutputDirectory
设置true,也不会清理其他目录中其他文件