0
1

More than 3 years have passed since last update.

Google App Engine (Java 8) + Servlet API 3.1 + Gradle で Hello World

Last updated at Posted at 2019-12-29

概要

  • Google App Engine Java 8 スタンダード環境 + Servlet API 3.1 の構成でシンプルなサーブレットと JSP (Java Server Pages) をデプロイする

環境

  • Google App Engine Java 8 スタンダード環境
  • Java 8
  • Servlet API 3.1
  • Gradle 6.0

Google App Engine Java 8 スタンダード環境

Jetty 9 + Servlet API 3.1 (or 2.5) を使用可能。
開発する側としては war ファイルを作ってデプロイするように作れば OK なので Jetty のことは気にしなくても良い。

Migrating from Java 7 to Java 8 Runtime  |  App Engine standard environment for Java 8  |  Google Cloud

Jetty 9 supports both Servlet 2.5 and 3.1 web applications, including servlet annotations.

ソースコード

ソースコード一覧

├── build.gradle
├── settings.gradle
└── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           └── HelloServlet.java
        └── webapp
            ├── WEB-INF
            │   └── appengine-web.xml
            └── index.jsp

build.gradle

Gradle のビルド設定ファイル。

build.gradle
buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    // Google App Engine Gradle plugin を使用
    classpath 'com.google.cloud.tools:appengine-gradle-plugin:1.+'
  }
}

repositories {
  mavenCentral()
}

apply plugin: 'java'
apply plugin: 'war'

// App Engine tasks
apply plugin: 'com.google.cloud.tools.appengine'

dependencies {

  // HTML エスケープのために Apache Commons Text を使う
  implementation 'org.apache.commons:commons-text:1.8'

  // Servlet API 3.1 を使う
  providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
}

group = "com.example" // Generated output GroupId
version = "1.0.0" // Version in generated output

sourceCompatibility = '1.8'
targetCompatibility = '1.8'

settings.gradle

settings.gradle
rootProject.name = 'hello'

HelloServlet.java

https://プロジェクトID.appspot.com/hello にアクセスしたときに HTML を返すサーブレット。

package com.example;

import org.apache.commons.text.StringEscapeUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {

    resp.setContentType("text/html; charset=utf-8");

    PrintWriter out = resp.getWriter();
    out.println("<html><body>");
    out.println("<h1>Hello, Servlet World!</h1>");

    // システム・プロパティを出力する
    out.println("<h2>System Properties</h2>");
    Properties props = System.getProperties();
    for (Object k : new TreeMap<>(props).keySet()) {
      String key = (String) k;
      out.println(h(key) + ": " + h((String) props.get(key)) + "<br>");
    }

    // 環境変数を出力する
    out.println("<h2>Environment Variables</h2>");
    Map<String, String> env = System.getenv();
    for (String key : new TreeMap<>(env).keySet()) {
      out.println(h(key) + ": " + h(env.get(key)) + "<br>");
    }

    // ランタイム情報を出力する
    out.println("<h2>Runtime.getRuntime()</h2>");
    Runtime r = Runtime.getRuntime();
    out.println("freeMemory: " + r.freeMemory() + "<br>");
    out.println("maxMemory: " + r.maxMemory() + "<br>");
    out.println("totalMemory: " + r.totalMemory() + "<br>");

    out.println("</body></html>");
    out.flush();
    out.close();
  }

  private static String h(String s) {
    return StringEscapeUtils.escapeHtml4(s);
  }
}

index.jsp

https://プロジェクトID.appspot.com/ にアクセスしたときに HTML を返す JSP ファイル。

index.jsp
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Hello, JSP!</title>
</head>
<body>
<p>Hello, JSP!</p>
</body>
</html>

appengine-web.xml

appengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  <runtime>java8</runtime>
  <threadsafe>true</threadsafe>
  <instance-class>F1</instance-class>
  <automatic-scaling>
    <target-cpu-utilization>0.95</target-cpu-utilization>
    <min-instances>0</min-instances>
    <max-instances>1</max-instances>
    <max-concurrent-requests>10</max-concurrent-requests>
  </automatic-scaling>
  <!-- システム・プロパティを設定できる -->
  <system-properties>
    <property name="com.example.HelloServlet.message" value="Hello, system property."/>
  </system-properties>
  <!-- 環境変数を設定できる -->
  <env-variables>
    <env-var name="COM_EXAMPLE_HELLOSERVLET_MESSAGE" value="Hello, environment variable." />
  </env-variables>
</appengine-web-app>

オペレーション

Google App Engine Gradle plugin のタスク

Google App Engine Gradle plugin の機能を使ってデプロイなどができる。
gradle tasks コマンドで実行可能なタスクを確認できる。

$ gradle tasks

> Task :tasks

------------------------------------------------------------
Tasks runnable from root project
------------------------------------------------------------

App Engine Standard environment tasks
-------------------------------------
appengineDeploy - Deploy an App Engine application
appengineDeployCron - Deploy Cron configuration
appengineDeployDispatch - Deploy Dispatch configuration
appengineDeployDos - Deploy Dos configuration
appengineDeployIndex - Deploy Index configuration
appengineDeployQueue - Deploy Queue configuration
appengineRun - Run an App Engine standard environment application locally
appengineShowConfiguration - Show current App Engine plugin configuration
appengineStage - Stage an App Engine standard environment application for deployment
appengineStart - Run an App Engine standard environment application locally in the background
appengineStop - Stop a locally running App Engine standard environment application
explodeWar - Explode a war into a directory
(以下略)

gradle appengineRun でローカルにサーバを起動

gradle appengineRun でローカルサーバ http://localhost:8080/ を起動できる。

$ gradle appengineRun

gradle appengineDeploy で Google App Engine にデプロイ

gradle appengineDeploy で Google App Engine にデプロイできる。
デプロイ前には「gcloud config set project プロジェクトID」でデプロイ先のプロジェクトIDを指定しておく。

$ gradle appengineDeploy

参考資料

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1