Hello World avec Google App Engine (Java 8) + Spring Boot + Gradle

Aperçu

--Créez une simple application Web d'affichage Hello World avec l'environnement standard Google App Engine Java 8 + configuration Spring Boot

environnement

Code source

Liste des codes sources

├── build.gradle
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── helloworld
    │   │               ├── HelloworldApplication.java
    │   │               ├── HelloworldController.java
    │   │               ├── HelloworldErrorController.java
    │   │               └── HelloworldServletInitializer.java
    │   ├── resources
    │   │   ├── application.yml
    │   │   ├── static
    │   │   │   └── assets
    │   │   │       └── helloworld.png
    │   │   └── templates
    │   │       ├── error.html
    │   │       └── helloworld.html
    │   └── webapp
    │       └── WEB-INF
    │           └── appengine-web.xml
    └── test
        └── java
            └── com
                └── example
                    └── helloworld
                        └── HelloworldApplicationTests.java

build.gradle

Un fichier qui décrit le processus lié à la création dans Gradle. Le plug-in Google App Engine Gradle utilise la série version 2.

build.gradle


buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    //Utiliser le plugin Spring Boot Gradle
    classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.2.0.RELEASE'
    //Utiliser le plugin Gradle de Google App Engine
    classpath 'com.google.cloud.tools:appengine-gradle-plugin:2.2.0'
  }
}

plugins {
  //Introduction du plug-in Java
  id 'java'
  //Introduction du plug-in War
  id 'war'
  // https://plugins.gradle.org/plugin/org.springframework.boot
  id 'org.springframework.boot' version '2.2.0.RELEASE'
  // https://plugins.gradle.org/plugin/io.spring.dependency-management
  id 'io.spring.dependency-management' version '1.0.8.RELEASE'
}

//Introduction du plug-in App Engine
apply plugin: 'com.google.cloud.tools.appengine'

repositories {
  mavenCentral()
}

dependencies {
  //Dernière version de l'API App Engine
  implementation 'com.google.appengine:appengine-api-1.0-sdk:+'
  // Thymeleaf
  implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
  // Spring Web
  implementation 'org.springframework.boot:spring-boot-starter-web'
  //Tomcat intégré n'est pas utilisé lors du déploiement
  providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
  // Test
  testImplementation('org.springframework.boot:spring-boot-starter-test') {
    //Exclure la prise en charge de JUnit 4
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
  }
}

test {
  //Activer la prise en charge de JUnit 5
  useJUnitPlatform()

  testLogging {
    //Afficher la sortie standard et la sortie d'erreur standard pendant le test
    showStandardStreams true
    //Événement de sortie(TestLogEvent)
    events 'started', 'skipped', 'passed', 'failed'
  }
}

//ID et version du groupe d'applications Web
group   = "com.example.helloworld"
version = "0.0.1"

//Utilisez Java 8
sourceCompatibility = '1.8'
targetCompatibility = '1.8'

//Paramètres des tâches Google App Engine
appengine {
  //Paramètres de déploiement
  // GCLOUD_Si vous spécifiez CONFIG
  //Les informations du projet définies dans gcloud config sont définies
  deploy {
    //Déployer l'ID de projet Google Cloud de destination
    projectId = "GCLOUD_CONFIG"
    //Version de l'application Web reflétée par le déploiement
    //Si non spécifié, un nouveau sera généré
    version = "GCLOUD_CONFIG"
  }
}

//Exécuter des tests avant le déploiement
appengineDeploy.dependsOn test
appengineStage.dependsOn test

référence:

settings.gradle

Si vous ne définissez pas setting.gradle, vous irez dans le répertoire parent pour trouver setting.gradle, alors mettez-le également dans un seul projet.

settings.gradle


rootProject.name = 'helloworld'

HelloworldApplication.java

Classe d'application. J'écris uniquement le traitement de routine pour l'utilisation de Spring Boot.

package com.example.helloworld;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloworldApplication {

  public static void main(String[] args) {
    SpringApplication.run(HelloworldApplication.class, args);
  }
}

HelloworldController.java

Classe de contrôleur.

package com.example.helloworld;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloworldController {

  /**
   * application.Message obtenu de yml.
   */
  @Value("${application.message}")
  private String applicationYamlMessage;

  /**
   *Renvoie la réponse de la première page.
   *
   * @retour d'informations sur l'affichage de la page
   */
  @GetMapping("/")
  public ModelAndView index() {

    System.out.println("HelloworldController#index");

    //Obtenu à partir des propriétés du système
    String systemPropertyMessage = System.getProperty("com.example.helloworld.message");

    //Définissez les données à afficher
    ModelAndView mav = new ModelAndView();
    mav.addObject("systemPropertyMessage", systemPropertyMessage);
    mav.addObject("applicationYamlMessage", applicationYamlMessage);
    mav.setViewName("helloworld"); //Afficher le nom. Spécifiez le fichier de modèle Thymeleaf

    return mav;
  }

  /**
   *Une méthode de test qui affiche une page d'erreur.
   */
  @GetMapping("/exception/")
  public void exception() {
    System.out.println("HelloworldController#exception");
    throw new RuntimeException("This is a sample exception.");
  }
}

HelloworldErrorController.java

Classe de contrôleur d'erreur pour l'ensemble de l'application Web. Il gère Not Found etc. qui ne peut pas être capturé par une classe de contrôleur générale. Seul le traitement minimum est décrit ici, mais personnalisez-le si nécessaire.

package com.example.helloworld;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 *Contrôleur d'erreur pour l'ensemble de l'application Web.
 *Classe d'implémentation d'interface ErrorController.
 */
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}") //Mappage vers la page d'erreur
public class HelloworldErrorController implements ErrorController {

  /**
   *Chemin de la page d'erreur.
   */
  @Value("${server.error.path:${error.path:/error}}")
  private String errorPath;

  /**
   *Renvoie le chemin de la page d'erreur.
   *
   * @return Chemin de la page d'erreur
   */
  @Override
  public String getErrorPath() {
    return errorPath;
  }

  /**
   *Renvoie un objet ModelAndView pour la réponse.
   *
   * @param req demande d'informations
   * @informations de réponse param mav
   * @Objet ModelAndView pour la réponse HTML de retour
   */
  @RequestMapping
  public ModelAndView error(HttpServletRequest req, ModelAndView mav) {

    System.out.println("HelloWorldErrorController#error");

    //404 introuvable pour une erreur
    //Le code du stator et le contenu de sortie peuvent être personnalisés selon les besoins.
    HttpStatus status = HttpStatus.NOT_FOUND;
    mav.setStatus(status);
    mav.setViewName("error"); // error.html
    return mav;
  }
}

HelloworldServletInitializer.java

Classe d'implémentation WebApplicationInitializer requise pour l'environnement dans lequel le fichier WAR est déployé et exploité. Google App Engine requiert cette classe pour déployer et exécuter des fichiers WAR.

package com.example.helloworld;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

public class HelloworldServletInitializer extends SpringBootServletInitializer {

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    System.out.println("HelloworldServletInitializer#configure");
    return application.sources(HelloworldApplication.class);
  }
}

Référence: [SpringBootServletInitializer \ (Spring Boot Docs 2 \ .2 \ .0 \ .RELEASE API )](https://docs.spring.io/spring-boot/docs/2.2.0.RELEASE/api/org/ springframework / boot / web / servlet / support / SpringBootServletInitializer.html)

application.yml

Un fichier qui décrit les informations de configuration de l'application Web. Il peut également s'agir de application.properties. Cette fois, seules les informations propres à l'application sont définies.

application:
  message: Hello, application yaml.

helloworld.png

Une image placée comme un échantillon montrant le stockage de fichiers statiques. Si vous placez le fichier statique dans src / main / resources / static, il sera mappé sur http: // hostname /. Cette fois, lorsque vous accédez à http: //hostname/assets/helloworld.png, le fichier src / main / resources / static / assets / helloworld.png est livré.

error.html

Fichier de modèle HTML Thymeleaf à afficher lorsqu'une erreur se produit. Cette fois, la valeur dynamique n'est pas incorporée, mais il est possible de définir la valeur dans la classe du contrôleur d'erreur selon les besoins et de la personnaliser pour qu'elle s'affiche du côté du modèle.

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>404 Not Found</title>
</head>
<body>
<h1>404 Not Found</h1>
</body>
</html>

helloworld.html

Un fichier de modèle HTML Thymeleaf pour afficher les valeurs définies par la classe de contrôleur.

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Hello, world.</title>
</head>
<body>
<h1>Hello, world.</h1>
<div th:text="'System Property: ' + ${systemPropertyMessage}"></div>
<div th:text="'application.yml: ' + ${applicationYamlMessage}"></div>
<div><img src="./assets/helloworld.png "></div>
</body>
</html>

appengine-web.xml

Fichier de configuration pour Google App Engine. Décrivez les informations de l'application Web.

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">

  <!-- Java VM -->
  <runtime>java8</runtime>

  <!--Paramètre sans fil-->
  <threadsafe>true</threadsafe>

  <!--Paramètre de mise à l'échelle automatique pour le nombre d'instances-->
  <automatic-scaling>
    <!--Lancer une nouvelle instance lorsque le facteur de charge du processeur spécifié ici est dépassé-->
    <target-cpu-utilization>0.95</target-cpu-utilization>
    <!--Nombre minimum d'instances. S'il est défini sur 0, le nombre d'instances sera égal à 0 lorsqu'il n'est pas utilisé.-->
    <min-instances>0</min-instances>
    <!--Nombre maximum d'instances-->
    <max-instances>1</max-instances>
    <!--Nombre autorisé de demandes simultanées-->
    <max-concurrent-requests>80</max-concurrent-requests>
  </automatic-scaling>

  <!--Fichier statique-->
  <static-files>
    <include path="/assets/**.*"/>
  </static-files>

  <!--Propriétés système activées lors de l'exécution sur Google App Engine ou avec gradle appengineRun-->
  <system-properties>
    <property name="com.example.helloworld.message" value="Hello, system property."/>
  </system-properties>
</appengine-web-app>

référence: appengine-web.référence xml|Environnement standard Java 8 App Engine|  Google Cloud

HelloworldApplicationTests.java

Classe de test minimale. Seules les choses formelles sont décrites. Ne teste rien.

package com.example.helloworld;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class HelloworldApplicationTests {

  @Test
  void contextLoads() {
  }
}

opération

Lancer le test

Vous pouvez exécuter le test avec la tâche de test gradle.

$ gradle test 

Démarrez le serveur localement avec gradle appengineRun

Vous pouvez démarrer le serveur local http: // localhost: 8080 / avec gradle appengineRun.

$ gradle appengineRun

Déployer sur Google App Engine avec gradle appengineDeploy

Peut être déployé sur Google App Engine avec gradle appengineDeploy.

$ gradle appengineDeploy

Autre

La gestion des erreurs à l'échelle de l'application Web ne s'applique pas

Dans certains cas, le contrôleur d'erreurs n'utilise pas sa propre gestion des erreurs.

Déployer le descripteur: web.xml  |Environnement standard Java 8 App Engine|  Google Cloud

Remarque: actuellement, les gestionnaires d'erreurs personnalisés ne peuvent pas être configurés pour certaines conditions d'erreur. Plus précisément, vous ne pouvez pas personnaliser la page de réponse HTTP 404 si aucun mappage de servlet n'est défini pour une URL particulière. Vous ne pouvez pas non plus personnaliser la page "Erreur d'allocation 403" ou la page "Erreur du serveur 500" qui s'affiche en raison d'une erreur interne d'App Engine.

Quand je l'ai essayé, 404 Not Found n'était pas ma propre personnalisation sur le serveur que j'ai configuré localement avec gradle appengineRun. Le gradle appengineDeploy déployé sur Google App Engine affichait son propre 404 non trouvé personnalisé.

Matériel de référence

Recommended Posts

Hello World avec Google App Engine (Java 8) + Spring Boot + Gradle
Hello World avec Google App Engine (Java 11) + Spring Boot + Gradle
Hello World avec Google App Engine (Java 8) + API Servlet 3.1 + Gradle
Développement Google AppEngine avec Docker
Prise en charge de Java 1 1 par Google App Engine
Création d'un environnement de développement avec Maven sur Google App Engine [Java]
Utilisation du fichier de propriétés avec l'environnement flexible Java 8 de Google App Engine
Je ne peux plus déployer avec le moteur d'application Google
bonjour le monde avec ctypes
Bonjour le monde avec Docker
Bonjour le monde sur flacon
PIL en Python sur Windows8 (pour Google App Engine)
Premiers pas avec Google App Engine pour Python et PHP
Dessinez bonjour le monde avec mod_wsgi
Bonjour le monde avec Flask + Hamlish
Jusqu'à bonjour le monde avec zappa
J'ai essayé Google Sign-In avec Spring Boot + Spring Security REST API
Déployer des applications Go sur Google App Engine avec des actions GitHub
Python commençant par Hello world!
Bonjour tout le monde! Avec la communication CAN virtuelle
[Note] Sortie Hello world avec python
Utilisez ndb.tasklet avec Google App Engine
Hello World! Par QPython avec Braincrash
Hello World et détection de visage avec opencv-python 4.2
Java - Déployer le projet Spring Boot sur GAE
Bonjour le monde avec Raspberry Pi + Minecraft Pi Edition
Accéder à Azure Cosmos DB avec Spring Boot
[Python] Exécutez Flask sur Google App Engine
[Google App Engine] Objets utilisateur (traduction en japonais)
Utiliser des modules externes avec Google App Engine
Hello World! Par QPython avec Brainfu * k
J'ai essayé Java8 + Spring Boot avec GAE SE (et à propos de son environnement de développement)
Une application Web qui ne fait que Hello World avec le package net / http de Go