protobuf生成java工具类

     由于本人最近在学习Netty,里面涉及了protobuf编译生成java文件的过程,觉得敲命令行比较麻烦,故写了个.prorto文件自动生成java文件的工具类,遇到了不少坑,与大家分享一下,望多多指正。

转载请注明出处:https://blog.csdn.net/weixin_40929150/article/details/88775559

首先

     先配置protobuf的编译环境,本人是win10。

1、下载protoc-win64.zip,解压。

2、配置环境变量

protobuf生成java工具类_第1张图片

编写工具类

    这里主要运用的是java执行CMD命令的原理,其步骤就是:

   1、将.proto文件的路径解析拼成 --proto_path=

   2、将要输出的java文件路径解析拼成 --java_out=

   3、最后通过Runtime依次执行command

这是一个简单的工具类,并不复杂,配置好路径便可直接运行,一些要注意的地方已在注释说明

package netty.utils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * .proto文件编译成Java文件
 * @author:LiChong
 * @date:2019/3/23
 */
public class ProtoToJavaUtils {

	/**
	 * 当前项目路径
	 */
	private static String url = System.getProperty("user.dir");

	private static final String PROJECT_NAME = "mahjongtest";

	private static String proto_path = "\\src\\main\\resources\\proto";

	/**
	 * 这里一般不需要带包名,因为.proto文件一般为指定包名并自动生成对应的包
	 */
	private static String java_path = "\\src\\main\\java\\";

	/**
	 * 如果只是想要编译部分(指定)proto文件
	 * 子包下必须带路径,eg:\\user\\user.proto or \\user.proto
	 */
	private static final List PROTO_FILES = new ArrayList<>();

	/**
	 * false: 编译部分(指定)proto文件,配合PROTO_FILES
	 * true: 编译 PROTO_PATH 路径下的所有.proto文件
	 */
	private static boolean isFiles = true;

	private static Runtime runtime = Runtime.getRuntime();

	public static void main(String[] args) {

		// 指定.proto文件可用
//		PROTO_FILES.add("\\user\\user.proto");
//		PROTO_FILES.add("\\Test.proto");
//		isFiles = false;

		// 编译
		transform();

	}

	private static void transform() {

		/*
		 * 这里要注意:
		 * 如果使用是idea里,有可能当前只是模块(module)而不是项目,获取到url可能只是项目路径
		 */
		if (!url.endsWith(PROJECT_NAME)) {
			url = url + "\\" + PROJECT_NAME;
		}
		proto_path = url + proto_path;
		java_path = url + java_path;
		System.out.println("JAVA_PATH:" + java_path);
		System.out.println("PROTO_PATH:" + proto_path);
		System.out.println("============================File out put===================================");

		String command = "";
		try {
			// 路径下全部
			if (isFiles) {
				File protoFile = new File(proto_path);

				if (protoFile.exists()) {
					File[] files = protoFile.listFiles();
					for (File file : files) {
						command = getCommand(file.getName());
						if (!command.isEmpty()) {
							outPutJava(command);
						}

					}
				}
			} else {
				// 指定.proto文件
				if (PROTO_FILES.size() > 0) {
					for (String protoFile : PROTO_FILES) {
						File file = new File(proto_path + protoFile);
						if (!file.exists()) {
							System.err.println("files is not exist : " + proto_path);
							continue;
						}
						command = getCommand(file.getName());
						if (!command.isEmpty()) {
							outPutJava(command);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 输出java文件
	 *
	 * @param command
	 * @throws IOException
	 */
	private static void outPutJava(String command) throws IOException {

		System.out.println(">>>:" + command);
		// 执行
		Process process = runtime.exec(command);
		// 打印结果
		InputStreamReader isr = new InputStreamReader(process.getErrorStream());
		BufferedReader br = new BufferedReader(isr);
		boolean isSuccess = true;
		String line = null;
		while ((line = br.readLine()) != null) {
			System.err.println("ERROR:" + line);
			isSuccess = false;
		}
		if (isSuccess) {
			System.out.println(">>>:success");
		}
		br.close();
		isr.close();
	}

	/**
	 * 获取CMD执行命令
	 *
	 * @param fileName
	 * @return
	 */
	private static String getCommand(String fileName) {
		StringBuffer command = new StringBuffer();
		command.append("protoc.exe")
				.append(" --java_out=").append(java_path)
				.append(" --proto_path=").append(proto_path)
				.append(" ").append(fileName);
		return command.toString();
	}
}

示例

protobuf生成java工具类_第2张图片

1、会打印出JAVA_PATH和PROTO_PATH

2、会打印执行命令

3、运行成功一般会输出success(有可能遇到特殊情况,success并不一定代表成功,主要看java文件有没有出来)

4、执行出错会输出ERROR

感谢观看~!!(⊙o⊙)…

你可能感兴趣的:(工具类,Netty)