Using Google Protocol Buffers (protobuf) in Java

Hello, Khabrovites. As part of the course "Java Developer. Professional" we have prepared a translation of useful material for you.



We also invite you to attend an open webinar on the topic "gRPC for microservices or not a single REST."






"Effective Java" («Java: »), , Java, Java 6. , , Java 7, Java 8 Java 9, 7 "Lambdas and Streams" («- »), 9 "Prefer try-with-resources to try-finally" ( «2.9. try-- try-finally») 55 "Return optionals judiciously" ( «8.7. Optional »). , , Java, . 85 "Prefer alternatives to Java Serialization" ( «12.1 Java») Google Protocol Buffers Java.





85 "Prefer alternatives to Java Serialization" (12.1 « Java») (Josh Bloch) , Java:





« , , — ».





« Java , ».





Java , , , « » ( , «» Java). , JSON (JavaScript Object Notation) Protocol Buffers (protobuf). Protocol Buffers, . JSON ( Java), Protocol Buffers java- . , Protocol Buffers Java .





Google Protocol Buffers « ». : « XML, , ». Protocol Buffers , Protocol Buffers Java.





-, Protocol Buffers, , protobuf GitHub, proto3 Language Guide ( proto2 Language Guide), Protocol Buffer Basics: Java, Java Generated Code Guide, API- Java API (Javadoc) Documentation, Protocol Buffers Maven-. Protocol Buffers 3.5.1.





Protocol Buffers Java "Protocol Buffer Basics: Java". , Java, , . Protocol Buffers, . .proto. album.proto, .





album.proto

syntax = "proto3";

option java_outer_classname = "AlbumProtos";
option java_package = "dustin.examples.protobuf";

message Album {
    string title = 1;
    repeated string artist = 2;
    int32 release_year = 3;
    repeated string song_title = 4;
}
      
      



, . , proto3 proto2, , . , option, Java- ( ) Java.





"message" "Album", . , (string), — (int32). , repeated. , Java option, Java- .





album.proto



, , «» Java (AlbumProtos.java



dustin.examples.protobuf



), Protocol Buffers. Java protoc, . Windows 10, protoc-3.5.1-win32.zip. protoc



album.proto



protoc --proto_path=src --java_out=dist\generated album.proto







album.proto



src, --proto_path



, build\generated



Java, --java_out



.





Java- AlbumProtos.java 1000 , , GitHub. import



( ). Java, protoc, Java Generated Code. , AlbumProtos Java-, album.proto, .





Java- AlbumProtos IDE . , .class .jar. 





, Java- Protocol Buffers. Album,



( GitHub).





Album.java

package dustin.examples.protobuf;

import java.util.ArrayList;
import java.util.List;

/**
 * Music album.
 */
public class Album {
    private final String title;

    private final List < String > artists;

    private final int releaseYear;

    private final List < String > songsTitles;

    private Album(final String newTitle, final List < String > newArtists,
        final int newYear, final List < String > newSongsTitles) {
        title = newTitle;
        artists = newArtists;
        releaseYear = newYear;
        songsTitles = newSongsTitles;
    }

    public String getTitle() {
        return title;
    }

    public List < String > getArtists() {
        return artists;
    }

    public int getReleaseYear() {
        return releaseYear;
    }

    public List < String > getSongsTitles() {
        return songsTitles;
    }

    @Override
    public String toString() {
        return "'" + title + "' (" + releaseYear + ") by " + artists + " features songs " + songsTitles;
    }

    /**
     * Builder class for instantiating an instance of
     * enclosing Album class.
     */
    public static class Builder {
        private String title;
        private ArrayList < String > artists = new ArrayList < > ();
        private int releaseYear;
        private ArrayList < String > songsTitles = new ArrayList < > ();

        public Builder(final String newTitle, final int newReleaseYear) {
            title = newTitle;
            releaseYear = newReleaseYear;
        }

        public Builder songTitle(final String newSongTitle) {
            songsTitles.add(newSongTitle);
            return this;
        }

        public Builder songsTitles(final List < String > newSongsTitles) {
            songsTitles.addAll(newSongsTitles);
            return this;
        }

        public Builder artist(final String newArtist) {
            artists.add(newArtist);
            return this;
        }

        public Builder artists(final List < String > newArtists) {
            artists.addAll(newArtists);
            return this;
        }

        public Album build() {
            return new Album(title, artists, releaseYear, songsTitles);
        }
    }
}
      
      



data- Album



, Protocol Buffers-, Album



(AlbumProtos.java



) Java- "" Album Java-. AlbumDemo



, GitHub.





Album



:





/**
 * Generates instance of Album to be used in demonstration.
 *
 * @return Instance of Album to be used in demonstration.
 */
public Album generateAlbum()
{
   return new Album.Builder("Songs from the Big Chair", 1985)
      .artist("Tears For Fears")
      .songTitle("Shout")
      .songTitle("The Working Hour")
      .songTitle("Everybody Wants to Rule the World")
      .songTitle("Mothers Talk")
      .songTitle("I Believe")
      .songTitle("Broken")
      .songTitle("Head Over Heels")
      .songTitle("Listen")
      .build();
}
      
      



AlbumProtos



,  Protocol Buffers, AlbumProtos.Album



, Album. , .





final Album album = instance.generateAlbum();
final AlbumProtos.Album albumMessage
    = AlbumProtos.Album.newBuilder()
        .setTitle(album.getTitle())
        .addAllArtist(album.getArtists())
        .setReleaseYear(album.getReleaseYear())
        .addAllSongTitle(album.getSongsTitles())
        .build();
      
      



, , Protocol Buffers, (Builder). Protocol Buffers, toByteArray()



, :





final byte[] binaryAlbum = albumMessage.toByteArray();
      
      



byte[]



Album



:





/**
 * Generates an instance of Album based on the provided
 * bytes array.
 *
 * @param binaryAlbum Bytes array that should represent an
 *    AlbumProtos.Album based on Google Protocol Buffers
 *    binary format.
 * @return Instance of Album based on the provided binary form
 *    of an Album; may be {@code null} if an error is encountered
 *    while trying to process the provided binary data.
 */
public Album instantiateAlbumFromBinary(final byte[] binaryAlbum) {
    Album album = null;
    try {
        final AlbumProtos.Album copiedAlbumProtos = AlbumProtos.Album.parseFrom(binaryAlbum);
        final List <String> copiedArtists = copiedAlbumProtos.getArtistList();
        final List <String> copiedSongsTitles = copiedAlbumProtos.getSongTitleList();
        album = new Album.Builder(
                copiedAlbumProtos.getTitle(), copiedAlbumProtos.getReleaseYear())
            .artists(copiedArtists)
            .songsTitles(copiedSongsTitles)
            .build();
    } catch (InvalidProtocolBufferException ipbe) {
        out.println("ERROR: Unable to instantiate AlbumProtos.Album instance from provided binary data - " +
            ipbe);
    }
    return album;
}
      
      



, parseFrom(byte [])



InvalidProtocolBufferException



. «» , , , — Album .





, Album , . System.identityHashCode() , , . Album



, , :





BEFORE Album (1323165413): 'Songs from the Big Chair' (1985) by [Tears For Fears] features songs [Shout, The Working Hour, Everybody Wants to Rule the World, Mothers Talk, I Believe, Broken, Head Over Heels, Listen]

AFTER Album (1880587981): 'Songs from the Big Chair' (1985) by [Tears For Fears] features songs [Shout, The Working Hour, Everybody Wants to Rule the World, Mothers Talk, I Believe, Broken, Head Over Heels, Listen]
      
      



, . Protocol Buffers, , ,  « » Java, Serializable, , . Effective Java («Java: ») , Java, , « Java , ».






"Java Developer. Professional".





«gRPC REST- ».








All Articles