1概要

この記事では、https://developers.google.com/protocol-buffers/[Google Protocol Buffer](protobuf)(言語に依存しない、よく知られているバイナリデータ形式)を見ていきます。ファイルをプロトコルで定義し、次にそのプロトコルを使用して、Java、C ++、C#、Go、Pythonなどの言語でコードを生成できます。

これはフォーマット自体の紹介記事です。 Spring Webアプリケーションでこのフォーマットを使用する方法を知りたい場合は、

この記事

を参照してください。


2 Mavenの依存関係の定義

プロトコルバッファを使用するにはJavaです、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22com.google.protobuf%22%20AND%20aにMaven依存関係を追加する必要があります。 %3A%22protobuf-java%22[protobuf-java]:

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>${protobuf.version}</version>
</dependency>

<properties>
    <protobuf.version>3.2.0</protobuf.version>
</properties>


3プロトコルの定義

例から始めましょう。非常に単純なプロトコルをprotobuf形式で定義できます。

message Person {
    required string name = 1;
}

これは必須フィールドを1つだけ持つ

Person

タイプの単純なメッセージのプロトコルです – nameは

string

タイプを持ちます。

プロトコルを定義するより複雑な例を見てみましょう。個人情報をprotobuf形式で格納する必要があるとしましょう。

パッケージprotobuf;

package protobuf;

option java__package = "com.baeldung.protobuf";
option java__outer__classname = "AddressBookProtos";

message Person {
    required string name = 1;
    required int32 id = 2;
    optional string email = 3;

    repeated string numbers = 4;
}

message AddressBook {
    repeated Person people = 1;
}

私たちのプロトコルは

Person

と__AddressBookの2つのタイプのデータから成ります。

必要なフィールドを定義したい場合 – そのようなフィールドなしでオブジェクトを作成すると

Exception

が発生することを意味するので、

required

キーワードを使用する必要があります。


optional

キーワードを使用してフィールドを作成すると、このフィールドを設定する必要がなくなります。

repeated

キーワードは可変サイズの配列型です。

すべてのフィールドにインデックスが付けられます – 番号1で示されるフィールドは、バイナリファイルの最初のフィールドとして保存されます。 2とマークされたフィールドは次に保存されます。これにより、フィールドをメモリ内でどのようにレイアウトするかをより適切に制御できます。


4 ProtobufファイルからのJavaコードの生成

ファイルを定義したら、それからコードを生成できます。

まず、私たちのマシンにhttps://github.com/google/protobuf/releases[install protobuf]をインストールする必要があります。これを行ったら、

protoc

コマンドを実行してコードを生成できます。

protoc -I=. --java__out=. addressbook.proto


protoc

コマンドは、

addressbook.proto

ファイルからJava出力ファイルを生成します。

java-out

は、生成されたクラスが作成されるディレクトリを指定します。

__

生成されたクラスは、定義されたメッセージのためのセッター、ゲッター、コンストラクター、そしてビルダーを持ちます。 protobufファイルを保存し、それらをバイナリ形式からJavaクラスに逆シリアル化するためのutilメソッドもあります。


5 Protobuf定義メッセージのインスタンスを作成する

生成されたコードを使用して、

Person

クラスのJavaインスタンスを簡単に作成できます。

String email = "[email protected]";
int id = new Random().nextInt();
String name = "Michael Program";
String number = "01234567890";
AddressBookProtos.Person person =
  AddressBookProtos.Person.newBuilder()
    .setId(id)
    .setName(name)
    .setEmail(email)
    .addNumbers(number)
    .build();

assertEquals(person.getEmail(), email);
assertEquals(person.getId(), id);
assertEquals(person.getName(), name);
assertEquals(person.getNumbers(0), number);

目的のメッセージタイプに対して

newBuilder()

メソッドを使用することで、流暢なビルダーを作成できます。すべての必須フィールドを設定した後、

build()

メソッドを呼び出して

Person

クラスのインスタンスを作成できます。


6. Protobuf

のシリアライズとデシリアライズ


Person

クラスのインスタンスを作成したら、作成したプロトコルと互換性のあるバイナリ形式でディスクに保存します。


AddressBook

クラスのインスタンスを作成し、そのオブジェクトに1人の人物を追加するとしましょう。

次に、そのファイルをディスクに保存します。自動生成コードには、

writeTo()

utilメソッドがあります。

AddressBookProtos.AddressBook addressBook
  = AddressBookProtos.AddressBook.newBuilder().addPeople(person).build();
FileOutputStream fos = new FileOutputStream(filePath);
addressBook.writeTo(fos);

そのメソッドを実行した後、私たちのオブジェクトはバイナリフォーマットにシリアライズされディスクに保存されます。ディスクからそのデータをロードし、それを

AddressBook

オブジェクトに逆シリアル化するために、

mergeFrom()

メソッドを使用できます。

AddressBookProtos.AddressBook deserialized
  = AddressBookProtos.AddressBook.newBuilder()
    .mergeFrom(new FileInputStream(filePath)).build();

assertEquals(deserialized.getPeople(0).getEmail(), email);
assertEquals(deserialized.getPeople(0).getId(), id);
assertEquals(deserialized.getPeople(0).getName(), name);
assertEquals(deserialized.getPeople(0).getNumbers(0), number);


7. 結論

この簡単な記事では、データをバイナリ形式で記述および保存するための標準、Google Protocol Bufferを紹介しました。

簡単なプロトコルを作成し、定義されたプロトコルに準拠したJavaインスタンスを作成しました。次に、protobufを使ってオブジェクトをシリアライズおよびデシリアライズする方法を見ました。

これらすべての例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/protobuffer[GitHubプロジェクト]で見つけることができます – これはMavenプロジェクトです。そのまま実行します。