我是配合这个学习的,记录了安装和学习过程中出现的bug:https://blog.csdn.net/briblue/article/details/53187780
安装protoc
1、先下载两个文件(不管系统是多少位,只管是不是windows或者mac等等):protoc-3.1.0-win32.zip protobuf-java-3.1.0.zip
这个添加到path是系统变量的path,路径要进入bin底下D:\Environment\protoc-3.1.0-win32\bin
从https://github.com/google/protobuf/releases下载protoc,如protoc-3.1.0-win32.zip,然后解压然后添加到path.
直接在全局位置cmd命令行中测试
protoc --version
正常情况应该打印版本信息,说明添加成功。
2、将protoc复制到protocol buffer解压的目录。
下载:protobuf-java-3.1.0.zip
我将它解压在E盘
E:\xxxx\protobuf-java-3.1.0,那么E:\xxxx\protobuf-java-3.1.0\protobuf-3.1.0这个目录就当它是根目录。我用$ROOT表示。
将protoc.exe文件复制到$ROOT/src/目录下。
然后在命令行中定位到$ROOT/java/,
然后运行命令mvn package,
如果一切成功的话,就会在$ROOT/java/core/target/目录下生成protobuf-java-3.1.0.jar文件
获得这个jar方法有二:
最简单的:新建一个maven项目,在pom.xml使用这个依赖
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.1.0</version>
</dependency>
这个是教程里的:就是在命令行中定位到$ROOT/java/,执行了mvn package命令大概到这个位置会自动停下
我等了一段时间都没看到有反应,然后去文件夹里面看,
只生成了一些target类型的文件夹,还没有protobuf-java-3.1.0.jar,所以此时需要自己按回车,然后控制台就像疯了死循环一样
疯狂打印命令,还会有一些异常,不管它,直到它自己停止。
然后直到出现build success,这时候看文件夹,就有protobuf-java-3.1.0.jar文件了。
----------------------------------------------
编译代码,把protoc弄成java:
1、这里记得$ROOT就是E:\xxxx\protobuf-java-3.1.0\protobuf-3.1.0
2、在控制台进入到adressbook.proto文件所在位置,然后再执行命令,记得命令在这里有一个空格java_out=. addressbook
3、然后会在adressbook.proto文件所在位置生成com/example/tutorial/AddressBookProtos.java文件
具体步骤:
在下载的protobuf-java-3.1.0.zip解压后,我们定义它的根目录为$ROOT。它下面有一个examples文件夹,里面有个adressbook.proto文件,.proto就是protocol buffer的文件格式后缀。
我们将之前生成的protobuf-java-3.1.0.jar复制到该目录下。然后执行下面的命令
protoc --java_out=. addressbook.proto
它就会自动生成com/example/tutorial/AddressBookProtos.java文件。
----------------------------------------
在java项目中测试
在IDE中新建项目,然后添加StudentOuterClass.java文件,并且添加protobuf-java-3.1.0.jar。
我是直接新建简单的java项目,然后在WEB-INF下的lib文件夹直接添加protobuf-java-3.1.0.jar,
这时候StudentOuterClass.java会报错,因为那个jar没有导入到项目引用jar里面,只是简单的放在项目而已。
右键该jar,选择add/as library。
然后可以新建一个测试类或者直接在StudentOuterClass.java添加内容,给它一个main方法就可以添加代码了。
-----------------------------------------
Bug
D:\Environment\protobuf-java-3.1.0\Demo>protoc --java_out=. rfq.proto
rfq.proto:14:32: Field number 23 has already been used in "Rfq" by field "skill".
原因:定义后面的数值重复了,如:23
message Rfq{
string skill = 23;
repeated int32 array = 23 [packed = true];
}
----------------------------------------
Rfq.proto: The first enum value must be zero in proto3.
在proto3枚举值第一个必须是0,其他的随意
在proto2,每个属性前必须加required,optional,repeated
----------------------------------------
编译命令解释:
protoc --java_out=. Rfq.proto
编译成java文件的时候,该命令不区分proto文件的名字,它对应生成的只是class 的类名
public final class RfQ {}
完整命令:
protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR path/to/file.proto
proto_path=IMPORT_PATH 默认当前目录
cpp_out 生成的c++文件目录
java_out 生成的java文件目录
pytho_out 生成的python文件目录
–proto_path等同于-I选项,它的意思是等待编译的.proto文件所在的目录,可以指定多个,如果不指定的话默认是当前目录。
path/to/file.proto 等待编译的proto数据文件。
在同一目录下编译多个proto文件
protoc -I=. --java_out=. Info.proto Student.proto
------------------------------------------
import "Info.proto";
就算导入了别的proto文件,如message Info
option java_package="com.frank.protocdemo"; 编译后生成的类在当前目录下的存放位置,如果当前没有文件夹,就会自动新建文件夹
option java_outer_classname="StudentDemo"; 编译后生成的类名