概要
- 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 のビルド設定ファイル。
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
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 ファイル。
<!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
<?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