美文网首页bugstac...
Protobuf系列-2.在Java项目中使用

Protobuf系列-2.在Java项目中使用

作者: AlstonWilliams | 来源:发表于2017-11-10 09:59 被阅读569次

    在上一篇文章中,我们介绍了如何安装Protoc,以及编译一个proto文件.

    在这篇文章中,我们将会介绍如何在项目中使用这些编译出来的文件.

    创建一个maven项目

    通过下面这条命令创建一个最简单的maven项目就好:
    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

    它会在当前目录下生成一个名为my-app的项目.

    这个项目的初始结构如下:

    我们可以看到,其中生成的的App.java以及AppTest.java,我们并不需要,所以直接给删掉就好了.

    然后,我们需要向其中添加一个protobuf的依赖,因为生成的Java文件需要这个依赖中的内容.

    pom.xml中添加如下内容:

        <dependency>
          <groupId>com.google.protobuf</groupId>
          <artifactId>protobuf-java</artifactId>
          <version>3.4.0</version>
        </dependency>
    

    注意上面的那个版本应该跟你安装的protoc版本一致.

    创建proto文件并生成Java文件

    我们在项目的根目录下,创建一个src/main/java/proto文件夹,并编写一个名为addressbook.proto的文件:

    syntax = "proto3";
    
    package com.mycompany.app;
    
    option java_package = "com.mycompany.app";
    option java_multiple_files = true;
    option java_outer_classname = "AddressBookProtos";
    
    message Person {
    
        string name = 1;
        int32 id = 2;
        string email = 3;
    
        enum PhoneType {
            MOBILE = 0;
            HOME = 1;
            WORK = 2;
        }
    
        message PhoneNumber {
    
            string number = 1;
            PhoneType type = 2;
    
        }
    
        repeated PhoneNumber phones = 4;
    
    }
    
    message AddressBook {
    
        repeated Person people = 1;
    
    }
    

    注意上面的这个文件中,option java_package部分,应该给你的项目中你想存放生成的文件的包名一致.

    通过protoc --java_out=. addressbook.proto命令,可以生成Java源文件.

    然后,我们需要将生成的这些源文件拷贝到项目根目录下的src/main/java/com/mycompany/app目录中.

    这里需要注意的是,如果你在写proto文件时,其中option java_package选项指定的目录跟你想存放的目录不一样的话,需要手动修改一下生成的文件中的包名.

    然后,我们在src/main/java/com/mycompany/app下,创建一个Java源文件,其内容如下:

    package com.mycompany.app;
    
    import java.io.*;
    
    public class AddPerson {
    
        static Person promptForAddress(BufferedReader stdin, PrintStream stdout) throws IOException {
    
            Person.Builder person = Person.newBuilder();
    
            stdout.print("Enter person ID: ");
            person.setId(Integer.valueOf(stdin.readLine()));
    
            stdout.print("Enter name: ");
            person.setName(stdin.readLine());
    
            stdout.print("Enter email address (blank for none): ");
            String email = stdin.readLine();
            if (email.length() > 0)
                person.setEmail(email);
    
            while (true) {
    
                stdout.print("Enter a phone number (or leave blank to finish)");
                String telephone = stdin.readLine();
                if (telephone.length() == 0)
                    break;
    
                Person.PhoneNumber.Builder phoneNumber = Person.PhoneNumber.newBuilder();
                phoneNumber.setNumber(telephone);
    
                stdout.print("Is this a mobile, home, or work phone? ");
                String type = stdin.readLine();
                if (type.equals("mobile"))
                    phoneNumber.setType(Person.PhoneType.MOBILE);
                else if (type.equals("home"))
                    phoneNumber.setType(Person.PhoneType.HOME);
                else if (type.equals("work"))
                    phoneNumber.setType(Person.PhoneType.WORK);
                else {
                    stdout.print("Unknown phone type. Using default");
                    phoneNumber.setType(Person.PhoneType.HOME);
                }
    
                person.addPhones(phoneNumber);
    
            }
    
            return person.build();
    
        }
    
        public static void main(String[] args) throws Exception {
    
            if (args.length != 1) {
                System.err.println("Usage: AddPerson ADDRESS_BOOK_FILE");
                System.exit(-1);
            }
    
            AddressBook.Builder addressBook = AddressBook.newBuilder();
    
            try {
                addressBook.mergeFrom(new FileInputStream(args[0]));
            } catch (FileNotFoundException e) {
                System.out.println(args[0] + " doesn't exist. Creating file.");
            }
    
            addressBook.addPeople(promptForAddress(new BufferedReader(new InputStreamReader(System.in)), System.out));
    
            FileOutputStream fileOutputStream = new FileOutputStream(args[0]);
            addressBook.build().writeTo(fileOutputStream);
            fileOutputStream.close();
    
        }
    
    }
    
    

    它的作用是,让你输入一个Person的信息,并且保存到你指定的文件中.

    那么如何编译这个文件呢?

    进入到src/main/java这个目录下,执行下面的命令:

    ** javac -cp .:/opt/mvn/resp/com/google/protobuf/protobuf-java/3.4.0/protobuf-java-3.4.0.jar com/mycompany/app/AddPerson.java**

    其中你需要把protbuf-java的路径换成你的机器上的路径.

    编译完成后,通过java -cp .:/opt/mvn/resp/com/google/protobuf/protobuf-java/3.4.0/protobuf-java-3.4.0.jar com/mycompany/app/AddPerson hello这条命令来运行刚刚AddPerson文件.输入完Person的信息后,我们会看到在当前目录下,会生成一个十六进制的hello文件.

    我们打开这个16进制文件,可以看到其中的内容为:

    0A 08 0A 04 66 73 64 61 10 01
    

    其中保存了一些元数据以及我输入的数据的十六进制编码.

    就这样就完成了.

    总结

    在这篇文章中,我们一步步介绍了如何创建一个Java并和protobuf结合.

    这篇文章中,我只介绍了一部分用法,很不全面.

    请去查看官方文档来获取更加全面的信息.

    关于Protobuf的官方文档,后续我可能会翻译出来,也是放在这个系列中.

    相关文章

      网友评论

        本文标题:Protobuf系列-2.在Java项目中使用

        本文链接:https://www.haomeiwen.com/subject/rtwvmxtx.html