Java Servlet WEBアプリの Hello World!

# Java Servlet WEBアプリの Hello World!

## 目的

Java Servlet で最小構成のWEBアプリを作成して理解を深めます。  

## 実現すること

ローカル環境 (Ubuntu) で Java Servlet war ファイル形式のWEBアプリをビルド・起動します。

## 技術背景

### Java Servlet とは？  

<details>
<summary>こちらを展開してご覧いただけます。</summary>

### [Java Servlet](https://docs.oracle.com/javaee/7/tutorial/servlets.htm#BNAFD)

Java Servlet は、Java プログラムによって動作するサーバーサイドの WEB コンポーネントであり、HTTP リクエストを受信して HTTP レスポンスを生成する機能を提供します。  

以下は Java Servlet の主な特徴とメリットです。  

#### プラットフォームの独立性

Java Servlet は Java で開発されており、プラットフォームに依存しないため、どのオペレーティングシステム上でも動作することができます。

#### 大規模な WEB アプリケーションの開発が可能

Java Servlet を使用することで、大規模な WEB アプリケーションを開発することができます。Java Servlet は、スケーラビリティやセキュリティなど、高度な機能を提供するため、大規模な WEB アプリケーションの開発に最適です。

#### リクエストとレスポンスの制御

Java Servlet は、HTTP リクエストとレスポンスを制御することができます。つまり、クライアントから送信されたリクエストを処理し、必要に応じて HTTP レスポンスを生成することができます。

#### セッション管理

Java Servlet は、セッション管理をサポートするため、WEB アプリケーションでユーザーの状態を管理することができます。

#### プログラマブルなAPI

Java Servlet は、プログラマブルな API を提供するため、開発者が WEB アプリケーションの振る舞いを制御することができます。また、Java Servlet は、多数のサードパーティ製ライブラリをサポートするため、WEB アプリケーションの開発を容易にします。

</details>

## 開発環境

+ Windows 11 Home 22H2 を使用しています。  
+ [WSL](https://learn.microsoft.com/ja-jp/windows/wsl/about) の Ubuntu を操作していきますので macOS の方も参考にして頂けます。  

<details>

WSL (Microsoft Store アプリ版)

```sh
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
```

Ubuntu

```sh
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
```

Java JDK [※ Java JDK の導入と Hello World!](https://qiita.com/hiroxpepe/items/8650664e466906a57996)

```sh
$ java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)
```

Maven [※ Maven の導入と Hello World!](https://qiita.com/hiroxpepe/items/40f7f199b9be7f9e3b5b)

```sh
$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.17, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
```

</details>

※ この記事では基本的に Ubuntu のターミナルで操作を行います。

## "Hello World" を表示する手順

### プロジェクトフォルダの作成

※ ~/tmp/hello-servlet をプロジェクトフォルダとします。  

```sh
$ cd ~
$ mkdir -p tmp/hello-servlet
$ cd ~/tmp/hello-servlet
```

### Servlet クラスの作成

```sh
$ mkdir -p src/main/java/com/example/servlet
$ vim src/main/java/com/example/servlet/HelloServlet.java
```

ファイルの内容

```java:HelloServlet.java
package com.example.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("message", "Hello World!");
        request.getRequestDispatcher("/WEB-INF/views/hello.jsp").forward(request, response);
    }
}
```

<details>
<summary>説明を開きます。</summary>

このコードは Java Servlet を実装しています。

+ @WebServlet アノテーションを使用して、"/hello" のリクエストパスにマッピングされた Servlet クラスを作成しています。

+ HelloServlet は、doGet() メソッドをオーバーライドし、HttpServletRequest と HttpServletResponse を受け取ります。 このサーブレットは、リクエスト属性に "message" という名前の文字列を設定し、JSP ファイルにフォワードします。 JSP ファイルは、設定されたメッセージを表示するために使用されます。

この Servlet は、Java Servlet API を使用して実装されており、WEB アプリケーションのリクエストとレスポンスを処理することができます。 Servlet API は、WEB アプリケーションの開発を簡素化し、再利用可能なコンポーネントの作成を可能にする多数のクラスとインタフェースを提供しています。

</details>

### HTML テンプレートの作成

```sh
$ mkdir -p src/main/webapp/WEB-INF/views/
$ vim src/main/webapp/WEB-INF/views/hello.jsp
```

ファイルの内容

```jsp:hello.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        <h1><c:out value="${message}" /></h1>
    </body>
</html>
```

<details>
<summary>説明を開きます。</summary>

このコードは、JSTL (JSP Standard Tag Library) を使用して、Java Servlet によって設定されたリクエスト属性の値を表示するための JSP (JavaServer Pages) を作成しています。  

この JSP では、リクエスト属性 "message" の値を取得し、h1 要素に表示しています。  

また、JSTL の c:out タグを使用して、HTML エスケープされたメッセージを表示するためのセキュリティ対策が行われています。  

</details>

### pom.xml (Maven) ファイルの作成

```sh
$ vim pom.xml
```

ファイルの内容

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>hello-servlet</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    <name>hello-servlet</name>

    <properties>
        <javax.servlet.version>4.0.1</javax.servlet.version>
        <java.version>11</java.version>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!-- Servlet -->
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${javax.servlet.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>${name}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>10.0.13</version>
                <configuration>
                    <scanIntervalSeconds>10</scanIntervalSeconds>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

### ディレクトリ・ファイル構成

```sh
$ tree
.
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           └── servlet
        │               └── HelloServlet.java
        └── webapp
            └── WEB-INF
                └── views
                    └── hello.jsp
```

### ビルドと起動

ビルド  
※ target/hello-servlet.war ファイルが作成されます。  
※ war ファイルは Java WEBアプリケーションのファイル形式です。  

```sh
$ mvn clean install
```

実行  
※ Maven のプラグインにより Jetty WEBサーバーを一時的に立ち上げ、その中で war ファイル形式の WEB アプリケーションが実行されます。  
※ アプリケーションは、Ctrl + C で終了出来ます。  

```sh
$ mvn jetty:run
```

WEBブラウザで確認

```sh
http://localhost:8080/hello
```

WEBブラウザに "Hello World!" と表示することが出来ました。

## まとめ

+ Ubuntu でのシンプルな構成の Java 開発環境で Java Servlet WEBアプリをビルド・実行することが出来ました。
+ 実際の開発では素の [Java Servlet](https://docs.oracle.com/javaee/7/tutorial/servlets.htm#BNAFD) を使う機会はもはや少ないと思われますが、Java WEB アプリの基本的な動作理解の助けにして頂けます。