mac环境下Maven实现protobuf编译
1、Maven项目创建:File -> new -> Project… -> 输入项目名称 -> finish:
2、在项目中创建proto目录:
该目录用来保存.proto
文件,此处将proto目录与src目录放置同一级,后面在配置时会用到
3、配置pom.xml
文件:
引入如下项目依赖
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.12.2</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.4</version>
<scope>provided</scope>
</dependency>
4、下面是最重要的一步:编译模块配置
配置pom.xml
文件的<build/>
模块,引入maven-antrun-plugin
插件,该插件用来将.proto
文件编译成.java
文件
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>generate-sources1</id>
<phase>process-test-resources</phase>
<configuration>
<tasks>
<exec executable="protoc">
<arg value="--java_out=src/main/java"/>
<arg value="proto/commands.proto"/>
<arg value="proto/model.proto"/>
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
在tasks标签中,
<exec executable="protoc">
用来指定使用“protoc”命令对代码进行编译;
<arg value="--java_out=src/main/java"/>
指定要输出的位置,注意:该输出目录只是大致的目录,在proto文件中还有其他相关代码
<arg value="proto/commands.proto"/>
用来指定proto文件,我创建了两个文件分别代表不同的功能commands.proto:指定接口,model.proto指定实体类
5、以model.proto代码举例
先粘贴上代码:
option java_package = "com.example.entities";
option java_multiple_files = true;
message AuthenticationSettingsTO {
optional string avatar = 1;
optional string username = 2;
optional string password = 3;
optional string phone = 5;
}
enum AllianceType {
Open = 0;
Closed = 1;
ByRequest = 2;
}
java_package
指定确定的目录,输出结果如下:
在pom.xml文件中--java_out
参数指定的是第一级目录,通过java_package
指定二级目录,java_multiple_files
参数指定每一个message都将输出一个文件。
在通过mvn package
对代码编译时,就已经将实际代码编译到jar
文件中,在其他项目将该proto项目引入即可使用;
6、import依赖问题
前面5步已经能实现基本.proto文件到.java文件的编译,可是还有一个问题:model.proto文件中是定义基本POJO类,在commands.proto文件中定义命令接口请求命令相关的数据信息;这事commands.proto中定义的数据就可能用到了model.proto中的数据;代码如下:
请求接口数据:commands.proto
// 测试:请求数据
message TestReq {
User user = 1;
}
// 测试:响应数据
message TestResp {
User user = 1;
}
POJO类数据:model.proto
message User {
int64 userId = 1;
string avatar = 2;
string nickname = 3;
}
在commands.proto文件中需要将model.proto导入
import "proto/model.proto";
下面代码是官方文档拿下来的:
protoc --proto_path=src/main/proto --java_out=src/main/java src/main/proto/model.proto src/main/proto/commands.proto
在pom.xml中指定--proto_path
参数,--java_out
参数,和.proto
文件的具体路径
<exec executable="protoc">
<arg value="--java_out=src/main/java"/>
<arg value="--proto_path=src/main/java/proto"/>
<arg value="src/main/java/proto/model.proto"/>
<arg value="src/main/java/proto/commands.proto"/>
</exec>
我将完整的pom.xml文件粘贴下来
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sqkb.game</groupId>
<artifactId>model-game</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jackson.version>2.5.1</jackson.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.12.2</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>generate-sources</id>
<phase>process-resources</phase>
<configuration>
<tasks>
<exec executable="protoc">
<arg value="--java_out=src/main/java"/>
<arg value="proto/model.proto"/>
<arg value="proto/commands.proto"/>
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
以及最终完整的目录结构:
commands.proto文件的全部代码
syntax = "proto3";
package com.proto;
import "proto/model.proto";
option java_package = "com.game.socket.proto.req";
option java_multiple_files = true;
enum RespStatus {
UNKNOWN_RESP = 0;
OK = 200;
NOT_AUTHORIZED = 401;
RELOAD = 409;
SERVER_ERROR = 500;
SERVER_BUSY = 502;
PLAYING_ON_ANOTHER_DEVICE = 503;
UNUSED1 = 504;
UNUSED2 = 505;
UNUSED3 = 506;
UNUSED4 = 507;
}
// 请求类型,每增加一个接口都要增加一个类型
enum ReqRepType {
UnknownReqRepType = 0;
Test = 1;
Batch = 2;
Sync = 3;
}
// 测试:请求数据
message TestReq {
User user = 1;
}
// 测试:响应数据
message TestResp {
User user = 1;
}
message WolfServiceReq {
int32 id = 1;
ReqRepType type = 2;
ReqSync reqSync = 100;
}
message WolfServiceResp {
RespSync respSync = 100;
}
// 同步接口
message ReqSync {
int32 overrideTutorialGroup = 1;
string overrideVariant = 2; //used for selecting specialised testing config
string countryCode = 3;
string deviceVer = 4;
}
message RespSync {
string configBaseUrl = 1;
string gameConfigVersion = 2;
string langConfigVersion = 3;
string newsConfigVersion = 4;
}
model.proto的全部代码
syntax = "proto3";
package com.proto;
option java_package = "com.game.socket.proto.entity";
option java_multiple_files = true;
message User {
int64 userId = 1;
string avatar = 2;
string nickname = 3;
}
message Chapter {
int64 userId = 1;
int32 level = 2;
int32 createTime = 3;
}
enum Platform {
NA = 0;
IOS = 1;
ANDROID = 2;
WEB = 3;
WINDOWS_PHONE = 4;
UNUSED5 = 5;
UNUSED6 = 6;
}
message ClientServerMessageHeader {
string version = 2;
string service = 3;
string tokenId = 4;
string authentication = 5;
Platform platform = 8;
string clide = 10;
}
message StatTO {
string id = 1;
int64 sum = 2;
repeated StatValueTO values = 3;
}
message StatValueTO {
int64 value = 1;
int64 time = 2;
}
注意:
在pom文件中如果有<arg value="--proto_path=src/main/java"/>
需要将proto文件写到配置的目录下src/main/java;如果没有proto_path配置,将默认在src同级目录下。