Aan de slag met Java

Deze tutorial is bedoeld voor gebruikers die nog nooit apps in de cloud hebben ontworpen, zoals technici en webontwikkelaars die de belangrijkste concepten willen leren om apps te ontwikkelen met Google Cloud.

Doelen

Bekijk de volgende gidsen voor andere taalspecifieke tutorials om zelf apps te ontwerpen:

Kosten

This tutorial uses the following billable components of Google Cloud:

The tutorial is designed to keep your resource usage within the limits of Google Cloud's Always Free tier. To generate a cost estimate based on your projected usage, use the pricing calculator. New Google Cloud users might be eligible for a free trial.

When you finish this tutorial, you can avoid continued billing by deleting the resources you created. For more information, see Cleaning up.

Voordat u begint

  1. Sign in to your Google Account.

    If you don't already have one, sign up for a new account.

  2. In the Cloud Console, on the project selector page, select or create a Cloud project.

    Go to the project selector page

  3. Zorg dat facturering is ingeschakeld voor uw project.

    Meer informatie over het inschakelen van facturering

  4. Voer de volgende stappen uit om een Firestore-database te maken in systeemeigen modus:
    1. Ga in de Cloud Console naar de pagina Firestore-viewer.
      Naar Firestore-viewer
    2. Klik in het scherm Selecteer een Firestore-modus op Systeemeigen modus selecteren.
    3. Selecteer een locatie voor uw Firestore-database. Deze locatie-instelling bepaalt bovendien de standaardlocatie van Google Cloud-resources voor uw Cloud-project. Deze locatie wordt gebruikt voor Google Cloud-services in uw Cloud-project waarvoor een locatie-instelling vereist is. Dit zijn uw standaard Cloud Storage-bucket en uw App Engine-app.
    4. Klik op Database maken.
  5. Enable the App Engine Admin, Cloud Storage, Cloud Logging, and Error Reporting APIs.

    Enable the APIs

  6. Open de broncode van de app in Cloud Shell.
    Naar Cloud Shell

    In Cloud Shell heeft u rechtstreeks vanuit uw browser opdrachtregeltoegang tot uw cloudresources.

  7. Klik op Doorgaan om de voorbeeldcode te downloaden en te wijzigen in de app-directory.
  8. Configureer de gcloud-tool in Cloud Shell om uw nieuwe Google Cloud-project te gebruiken:

        # Configure gcloud for your project
        gcloud config set project PROJECT_ID
        

    Vervang PROJECT_ID door de ID van het Google Cloud-project dat u met de Cloud Console heeft gemaakt.

    De gcloud opdrachtregeltool is de belangrijkste manier om via de opdrachtregel met uw Google Cloud-resources te communiceren. In deze tutorial gebruikt u de tool gcloud om uw app te implementeren en te controleren.

Uw app uitvoeren

  1. Als u Cloud Shell al gebruikt en geconfigureerd heeft voor Java 11, moet u de Java-alternatieven van de shell, JAVA_HOME en PATH-omgevingsvariabelen updaten om Java 8 te specificeren.
  2. Wijzig naar de 1-cloud-run-directory en voer de app uit:
        GOOGLE_CLOUD_PROJECT=PROJECT_ID mvn -Plocal clean jetty:run-exploded
        
    Vervang PROJECT_ID door de ID van het Google Cloud-project dat u heeft gemaakt.
  3. Klik in Cloud Shell op Voorbeeld op het web en selecteer Voorbeeld op poort 8080. Uw app wordt uitgevoerd in een nieuw venster.

Uw app implementeren in Cloud Run

Google Cloud biedt verschillende mogelijkheden om uw code uit te voeren. Voor dit voorbeeld gebruikt u Cloud Run om een schaalbare app te implementeren in Google Cloud. Cloud Run zorgt ervoor dat u geen servers hoeft te beheren en zich kunt concentreren op het schrijven van uw code. Daarnaast schaalt Cloud Run automatisch om onverwachte pieken in het verkeer op te vangen.

  1. Ontwerp de image met Jib:
    mvn package jib:build -Dimage gcr.io/PROJECT_ID/bookshelf

    Vervang PROJECT_ID door de ID van het Google Cloud-project dat u heeft gemaakt.

  2. En implementeer de image:
    gcloud run deploy bookshelf --image gcr.io/PROJECT_ID/bookshelf \
        --platform managed --region us-central1 --allow-unauthenticated
    Vervang PROJECT_ID door de ID van het Google Cloud-project dat u heeft gemaakt.

Als de implementatie succesvol is afgerond, voert deze een eindpunt uit naar de app die wordt uitgevoerd in Cloud Run, in de indeling:

https://bookshelf-abcdefghij-uc.a.run.app

Uw app kan nu worden bekeken via deze link, hierna YOUR_CODE_RUN_URL genoemd. Voer de URL in uw webbrowser in om de app te bekijken.

Homepage van Bookshelf-app

Uw gegevens opslaan met Firestore

U kunt geen informatie op uw App Engine-instanties opslaan: de informatie gaat verloren als u de instantie herstart en als u een nieuwe instantie maakt, bestaat de informatie helemaal niet. In plaats daarvan gebruikt u een database waarin al uw instanties informatie schrijven en lezen.

Google Cloud biedt verschillende mogelijkheden om uw gegevens op te slaan. In dit voorbeeld slaat u de gegevens voor elk boek op in Firestore. Firestore is een volledig beheerde, serverloze NoSQL-documentendatabase waarin u gegevens kunt opslaan en opzoeken. Firestore schaalt automatisch om zich aan de behoeften van uw app aan te passen en schaalt naar nul als u de app niet gebruikt. Voeg nu uw eerste boek toe.

  1. Voer de volgende URL in uw webbrowser in:

    https://PROJECT_ID.REGION_ID.r.appspot.com

    Vervang het volgende:

  2. Klik op Boek toevoegen om een boek voor uw geïmplementeerde app te maken.

    Een boek in de Bookshelf-app toevoegen
  3. Vul in het veld Titel Moby Dick in.
  4. Vul in het veld Auteur Herman Melville in.
  5. Klik op Opslaan. Nu staat er een item in uw Bookshelf-app.

    Moby Dick-item in Bookshelf-app
  6. Klik in de Cloud Console op Vernieuwen om de Firestore-pagina te vernieuwen. De gegevens worden weergegeven in Firestore. De Bookshelf-app slaat elk boek op als een Firestore-document met een unieke ID. Al deze documenten worden opgeslagen in een Firestore-collectie. In deze tutorial noemen we deze collectie 'boeken'. Voorbeeld van een Firestore-document.

Firestore slaat de boeken op in de Firestore-clientbibliotheek. In dit voorbeeld ziet u hoe u een Firestore-document ophaalt:

public class FirestoreDao implements BookDao {
      private CollectionReference booksCollection;

      public FirestoreDao() {
        Firestore firestore = FirestoreOptions.getDefaultInstance().getService();
        booksCollection = firestore.collection("books");
      }

      private Book documentToBook(DocumentSnapshot document) {
        Map<String, Object> data = document.getData();
        if (data == null) {
          System.out.println("No data in document " + document.getId());
          return null;
        }

        return new Book.Builder()
            .author((String) data.get(Book.AUTHOR))
            .description((String) data.get(Book.DESCRIPTION))
            .publishedDate((String) data.get(Book.PUBLISHED_DATE))
            .imageUrl((String) data.get(Book.IMAGE_URL))
            .createdBy((String) data.get(Book.CREATED_BY))
            .createdById((String) data.get(Book.CREATED_BY_ID))
            .title((String) data.get(Book.TITLE))
            .id(document.getId())
            .build();
      }

      @Override
      public String createBook(Book book) {
        String id = UUID.randomUUID().toString();
        DocumentReference document = booksCollection.document(id);
        Map<String, Object> data = Maps.newHashMap();

        data.put(Book.AUTHOR, book.getAuthor());
        data.put(Book.DESCRIPTION, book.getDescription());
        data.put(Book.PUBLISHED_DATE, book.getPublishedDate());
        data.put(Book.TITLE, book.getTitle());
        data.put(Book.IMAGE_URL, book.getImageUrl());
        data.put(Book.CREATED_BY, book.getCreatedBy());
        data.put(Book.CREATED_BY_ID, book.getCreatedById());
        try {
          document.set(data).get();
        } catch (InterruptedException | ExecutionException e) {
          e.printStackTrace();
        }

        return id;
      }

      @Override
      public Book readBook(String bookId) {
        try {
          DocumentSnapshot document = booksCollection.document(bookId).get().get();

          return documentToBook(document);
        } catch (InterruptedException | ExecutionException e) {
          e.printStackTrace();
        }
        return null;
      }

      @Override
      public void updateBook(Book book) {
        DocumentReference document = booksCollection.document(book.getId());
        Map<String, Object> data = Maps.newHashMap();

        data.put(Book.AUTHOR, book.getAuthor());
        data.put(Book.DESCRIPTION, book.getDescription());
        data.put(Book.PUBLISHED_DATE, book.getPublishedDate());
        data.put(Book.TITLE, book.getTitle());
        data.put(Book.IMAGE_URL, book.getImageUrl());
        data.put(Book.CREATED_BY, book.getCreatedBy());
        data.put(Book.CREATED_BY_ID, book.getCreatedById());
        try {
          document.set(data).get();
        } catch (InterruptedException | ExecutionException e) {
          e.printStackTrace();
        }
      }

      @Override
      public void deleteBook(String bookId) {
        try {
          booksCollection.document(bookId).delete().get();
        } catch (InterruptedException | ExecutionException e) {
          e.printStackTrace();
        }
      }

      private List<Book> documentsToBooks(List<QueryDocumentSnapshot> documents) {
        List<Book> resultBooks = new ArrayList<>();
        for (QueryDocumentSnapshot snapshot : documents) {
          resultBooks.add(documentToBook(snapshot));
        }
        return resultBooks;
      }

      @Override
      public Result<Book> listBooks(String startTitle) {
        Query booksQuery = booksCollection.orderBy("title").limit(10);
        if (startTitle != null) {
          booksQuery = booksQuery.startAfter(startTitle);
        }
        try {
          QuerySnapshot snapshot = booksQuery.get().get();
          List<Book> results = documentsToBooks(snapshot.getDocuments());
          String newCursor = null;
          if (results.size() > 0) {
            newCursor = results.get(results.size() - 1).getTitle();
          }
          return new Result<>(results, newCursor);
        } catch (InterruptedException | ExecutionException e) {
          e.printStackTrace();
        }
        return new Result<>(Lists.newArrayList(), null);
      }

      @Override
      public Result<Book> listBooksByUser(String userId, String startTitle) {
        Query booksQuery =
            booksCollection.orderBy("title").whereEqualTo(Book.CREATED_BY_ID, userId).limit(10);
        if (startTitle != null) {
          booksQuery = booksQuery.startAfter(startTitle);
        }
        try {
          QuerySnapshot snapshot = booksQuery.get().get();
          List<Book> results = documentsToBooks(snapshot.getDocuments());
          String newCursor = null;
          if (results.size() > 0) {
            newCursor = results.get(results.size() - 1).getTitle();
          }
          return new Result<>(results, newCursor);
        } catch (InterruptedException | ExecutionException e) {
          e.printStackTrace();
        }
        return new Result<>(Lists.newArrayList(), null);
      }
    }

Lees Gegevens toevoegen aan Firestore voor meer informatie over het gebruik van Firestore.

Geüploade bestanden opslaan in Cloud Storage

Nu u een boek heeft toegevoegd, is het tijd om de bijbehorende omslagafbeelding toe te voegen. U kunt geen bestanden op uw instanties opslaan. Een database is niet de juiste keuze voor afbeeldingsbestanden. Gebruik in plaats daarvan Cloud Storage.

Cloud Storage is de primaire opslagplaats voor blobs in Google Cloud. U kunt Cloud Storage gebruiken om app-items te hosten die u wilt delen in Google Cloud. Als u Cloud Storage wilt gebruiken, moet u een Cloud Storage-bucket maken. Dit is een basiscontainer waarin uw gegevens worden opgeslagen.

  1. Ga in de Cloud Console naar de Cloud Storage-browserpagina.

    Naar de Cloud Storage-browserpagina

  2. Klik op Bucket maken.
  3. Geef in het dialoogvenster Bucket maken een naam voor uw bucket op door de ID van uw Google Cloud-project achteraan de tekenreeks _bucket te zetten, zodat de naam eruitziet als YOUR_PROJECT_ID_bucket. De naam moet voldoen aan de vereisten voor bucketnamen. In alle andere velden mag de standaardwaarde blijven staan.
  4. Klik op Maken.
  5. Nadat u uw bucket heeft gemaakt, klikt u op Boek bewerken en selecteert u een afbeelding die u als boekomslag wilt uploaden. Gebruik bijvoorbeeld deze afbeelding uit het publieke domein:
    Moby Dick-boekomslag
  6. Klik op Opslaan. U wordt omgeleid naar de homepage. Nu staat er een item in uw Bookshelf-app.
    Moby Dick-item in Bookshelf-app

De Bookshelf-app stuurt geüploade bestanden naar Cloud Storage via de Cloud Storage-clientbibliotheek.

public class CloudStorageHelper {

      private final Logger logger = Logger.getLogger(CloudStorageHelper.class.getName());
      private static Storage storage = null;

      static {
        storage = StorageOptions.getDefaultInstance().getService();
      }

      /**
       * Uploads a file to Google Cloud Storage to the bucket specified in the BUCKET_NAME environment
       * variable, appending a timestamp to end of the uploaded filename.
       */
      public String uploadFile(FileItemStream fileStream, final String bucketName)
          throws IOException, ServletException {
        checkFileExtension(fileStream.getName());

        System.out.println("FileStream name: " + fileStream.getName() + "\nBucket name: " + bucketName);

        DateTimeFormatter dtf = DateTimeFormat.forPattern("-YYYY-MM-dd-HHmmssSSS");
        DateTime dt = DateTime.now(DateTimeZone.UTC);
        String dtString = dt.toString(dtf);
        final String fileName = fileStream.getName() + dtString;

        // the inputstream is closed by default, so we don't need to close it here
        @SuppressWarnings("deprecation")
        BlobInfo blobInfo =
            storage.create(
                BlobInfo.newBuilder(bucketName, fileName)
                    // Modify access list to allow all users with link to read file
                    .setAcl(new ArrayList<>(Arrays.asList(Acl.of(User.ofAllUsers(), Role.READER))))
                    .build(),
                fileStream.openStream());
        logger.log(
            Level.INFO, "Uploaded file {0} as {1}", new Object[] {fileStream.getName(), fileName});
        // return the public download link
        return blobInfo.getMediaLink();
      }

      /** Checks that the file extension is supported. */
      private void checkFileExtension(String fileName) throws ServletException {
        if (fileName != null && !fileName.isEmpty() && fileName.contains(".")) {
          String[] allowedExt = {".jpg", ".jpeg", ".png", ".gif"};
          for (String ext : allowedExt) {
            if (fileName.endsWith(ext)) {
              return;
            }
          }
          throw new ServletException("file must be an image");
        }
      }
    }

Bekijk de handleidingenlijst voor meer informatie over hoe u Cloud Storage gebruikt.

Uw app controleren met de operationele producten van Google Cloud

U heeft uw app geïmplementeerd en boeken gemaakt en aangepast. Gebruik App-prestatiebeheer om deze gebeurtenissen voor uw gebruikers te controleren.

Logboeken controleren met Cloud Logging

  1. Ga naar de Logboekviewer in de Google Cloud.

    Naar logboekviewer

    U kunt uw app in realtime controleren. Als er problemen zijn met uw app, is dit een van de eerste plaatsen die u moet nakijken.

    Stackdriver Log Viewer
  2. Selecteer in het dropdownmenu Resource Cloud Run Revision, bookshelf.

Error Reporting gebruiken om fouten te controleren

  1. Ga in de Cloud Console naar de pagina Error Reporting.
    Ga naar de pagina Error Reporting
    In Error Reporting ziet u eventuele fouten en excepties in uw app en kunt u hiervoor waarschuwingen instellen.
  2. Ga in uw browser naar de URL /errors in uw app.
    YOUR_CODE_RUN_URL/errors

    Hiermee wordt een nieuwe testexceptie gegenereerd die naar de operationele producten van Google Cloud wordt verstuurd.

  3. Ga in de Cloud Console terug naar de pagina Error Reporting. Hier verschijnt binnen enkele ogenblikken de nieuwe fout. Klik op Automatisch opnieuw laden om de pagina niet handmatig te hoeven vernieuwen.

    Foutmelding uit Error Reporting.

Opschonen

Doe het volgende om te voorkomen dat er kosten in rekening worden gebracht op uw Google Cloud Platform-account voor de resources die in deze tutorial zijn gebruikt:

Verwijder het project

  1. In the Cloud Console, go to the Manage resources page.

    Go to the Manage resources page

  2. In the project list, select the project that you want to delete and then click Delete .
  3. In the dialog, type the project ID and then click Shut down to delete the project.

Volgende stappen