Servlet+TomcatをMacbookProのローカルで起動(テキストエディタ+ターミナルonly)

ずっとIDE任せでServletのつくりをよく知らないままだったため、自マシンへ構築して勉強。

# 前提
マシン：Macbook Pro
OS：MacOS Mojave

基本的に以下ページ通りに作業しているが、Windows向けの部分が多々あったのでその辺りはアレンジ。
https://www.javadrive.jp/servlet/

「/Users/[macbookユーザ名]/」=「~/」と記載。

# 環境構築
## 1.Javaのダウンロード
すでにマシンにJavaが入っていたので割愛。バージョンは以下。

```
$java -version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
```

個人開発なのでJava利用は無償で大丈夫。
https://java.com/ja/download/
>新しいOracle Java SEのOracle Technology Networkライセンス契約は、以前のOracle Javaライセンスとは大きく異なります。 新しいライセンスでは、個人的な使用や開発目的での使用など、特定の使用が無償で許可されますが、以前のOracle Javaライセンスの下で認可されたその他の使用はできなくなりました。 この製品をダウンロードして使用する前に、条件をよくお読みください。

## 2.Tomcatのダウンロード
以下からダウンロードした。
http://tomcat.apache.org/

最新バージョン「9.0.30」にてダウンロード。Binary Distributions>Core>zipを選択。
READMEに以下のように書いてあったので、tarではなくzipにした。
http://us.mirrors.quenda.co/apache/tomcat/tomcat-9/v9.0.30/README.html
>NOTE: The tar files in this distribution use GNU tar extensions, and must be untarred with a GNU compatible version of tar. The version of tar on Solaris and Mac OS X will not work with these files.

zipを解凍し（ダブルクリックすると解凍してくれる）、わかりやすい場所へ移動。
自分の場合は以下のようにした。
1. Finderの「アプリケーション」を開いて「Tomcat」ディレクトリを作成
/Applications/Tomcat
2. 解凍したファイルをその下にコピペ。
/Applications/Tomcat/apache-tomcat-9.0.30

※Javaのバージョンによって入れられるTomcatが変わる。
（今回、自分のマシンにはJava8が入っていることを確認したので9.3.0.90を入れた）
詳しくは以下を参照。
https://tomcat.apache.org/whichversion.html

※homebrewを利用する方がらくちんと思われます。
https://formulae.brew.sh/formula/

###Tomcatの環境変数「CATALINA_HOME」を設定する
今回は別ターミナルを開いた場合でも環境変数を適用させたかったので、./bashrcと./bash_profileへ設定。
自分のマシンには./bashrcも./bash_profileも無かったので、今回作成した。
※開いているターミナルの中でだけ設定したいならexportコマンドでの設定でOK。
※./bashrcのみでは、新しくターミナル開いたときに環境変数が適用されなかった。

作成場所は以下のとおり。
~/.bash_profile
~/.bashrc

ファイル作成はターミナルで実施。

```
$cd ~/
$touch ./bash_profile
$touch ./bashrc
$ls -la
→ここで「.bash_profile」と「.bashrc」が出てくればOK
```

vimを使って中身を編集。

```
＄vi .bash_profile
→「a」キーでinsertモードにしてから、ファイルの中身を記載
→終わったら「esc」キーを押下して、「:wq」押下。まちがえたら「:q!」すれば保存されない

$vi .bashrc
→上記と同様。
```

各ファイルの中身は以下のとおり。

``` bash:.bash_profile
# ~/.bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi
```

``` bash:.bashrc
# EXPORT
export CATALINA_HOME=/Applications/Tomcat/apache-tomcat-9.0.30

# ALIAS
alias ll='ls -la'
```

※Mac OS Xにllコマンドは無いので、.bashrcで「ll」コマンドもどきを設定。あると便利。

ターミナルで、最後に設定した内容をマシンへ読み込ませる。
（これを行わないと、いつまでたっても何も起こらない）

```
＄source ~/.bashrc
＄source ~/.bash_profile
```

※環境変数設定については、以下サイトを参考にした
https://techracho.bpsinc.jp/hachi8833/2019_06_06/66396
https://qiita.com/hirokishirai/items/5a529c8395c4b336bf31
https://qiita.com/shyamahira/items/260862743e4c9794b5d2

※手順を参考にしたサイトだと「Tomcatが起動したままだと思うので〜」と記載があるけど、今回は特に起動なし。

# 実際の作業
## 3.index.htmlを表示
###任意の場所へディレクトリを作ってから中身を用意
自分の場合、以下へ作成
~/study/20191222_servlet-sample
→ここで作ったディレクトリがアプリケーションのルートになる

作ったディレクトリの下に、さらに以下のような構成のディレクトリを作成する。

[さっき作ったディレクトリ]
 + [helloworld]
 +  - [WEB-INF]
 +  +  - [classes]

###index.htmlを作成する。
置き場は以下。
~/study/20191222_servlet-sample/helloworld/

[さっき作ったディレクトリ]
 + [helloworld]
 +  - index.html←ここ
 +  - [WEB-INF]
 +  +  - [classes]

```html:index.html
<html>
  <head>
    <title>indexページの試験</title>
    <meta charset="utf-8" />
  </head>
  <body>
    <h1>test_トップページ</h1>
  </body>
</html>
```

※htmlファイルでmetaタグを利用して文字コードを指定しない場合、ファイルが文字化けする。
metaタグでの文字指定がないと、Shift-JISでデコードして文字化けしていた。

###アプリケーションのコンテキスト設定
Tomcat側に作ったディレクトリを認識してもらいたいので、設定ファイルを記述。

以下のとおりディレクトリを作る。
/Applications/Tomcat/apache-tomcat-9.0.30/conf
↓
/Applications/Tomcat/apache-tomcat-9.0.30/conf/Catalina/localhost

[Applications]
 + [Tomcat]
 +   -  [apache-tomcat-9.0.30]
 +   +   -  [conf]
 +   +   +   -  [Catalina]←ここ
 +   +   +   +   -  [localhost]←ここ

hello.xmlを以下へ作る。
/Applications/Tomcat/apache-tomcat-9.0.30/conf/Catalina/localhost/hello.xml

[Applications]
 + [Tomcat]
 +   -  [apache-tomcat-9.0.30]
 +   +   -  [conf]
 +   +   +   -  [Catalina]
 +   +   +   +   -  [localhost]
 +   +   +   +   +  - hello.xml←ここ

```xml:hello.xml
<Context path="/hello" docBase="/Users/[macbookユーザ名]/study/20191222_servlet-sample/helloworld" />
```

・xml名と、path名を合わせる必要があるとの事。
・指定された名前は、FQDNのうしろに付与される。※今回だと、http://localhost:8080/hello
・docBaseは、さきほど作成したディレクトリ名を指定。
→このようにTomcat内の設定ファイルで、アプリケーションのルートディレクトリを自由に指定できる。

### Tomcat起動、動作確認、終了
ターミナル経由でTomcat起動

```
$cd $CATALINA_HOME/bin
$./startup.sh
```

以下URLへアクセスし、さきほど作成したindex.htmlが表示されればOK
http://localhost:8080/hello

ターミナル経由でTomcat終了

```
$cd $CATALINA_HOME/bin
$./startup.sh
```

## 4.サーブレットの表示
###HelloWorld.javaファイルを作成
任意の場所へHelloWorld.javaを作成する。自分の場合、以下へ作成。
~/study/20191222_servlet

中身は https://www.javadrive.jp/servlet/context/index1.html と同じ。
※この例だと「out.close();」が無いので足すと良いかも。無くても動く

###HelloWorld.classを作成
コンパイルする。

```
cd ~/study/20191222_servlet
ls
```

→ここでHelloWorld.javaがあることを確認

```
javac HelloWorld.java
```

→コンパイルに失敗(サーブレット関連のjarが無いですよ〜と出てくる)
Servletを利用する場合は、servletのjarをクラスパス指定してコンパイルする必要がある。
（逆に言えば、それ以外は指定しなくてもよい）

```
javac -classpath $CATALINA_HOME/lib/servlet-api.jar HelloWorld.java
```

→コンパイルに成功してスッと終わる。

終わったらクラスファイルがある事を確認する。(lsコマンドやFinderで確認)

```
$ ll
total 16
drwxr-xr-x  4 hoge  staff  128 12 25 22:08 .
drwxr-xr-x  5 hoge  staff  160 12 25 21:43 ..
-rw-r--r--  1 hoge  staff  894 12 25 22:08 HelloWorld.class　←これ
-rw-r--r--@ 1 hoge  staff  583 12 25 22:08 HelloWorld.java
```

### HelloWorld.classを移動
HelloWorld.Classを、さきほど作ったディレクトリのclassesの下へ移動する。
~/study/20191222_servlet-sample/helloworld/classes/HelloWorld.class

[さっき作ったディレクトリ]
 + [helloworld]
 +  - index.html
 +  - [WEB-INF]
 +  +  - [classes]
 +  +  +  - HelloWorld.class←ここ

### web.xmlへマッピング設定を記載
置いたクラスファイルをURL経由でアクセスさせるために、web.xmlを設定する。
~/study/20191222_servlet-sample/helloworld/WEB-INF/web.xml

[さっき作ったディレクトリ]
 + [helloworld]
 +  - index.html
 +  - [WEB-INF]
 +  +  - web.xml←ここ
 +  +  - [classes]
 +  +  +  - HelloWorld.class

中身は https://www.javadrive.jp/servlet/context/index3.html と同じ。

```xml:web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  version="2.4">

  <servlet>
    <servlet-name>helloworld</servlet-name>
    <servlet-class>HelloWorld</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>helloworld</servlet-name>
    <url-pattern>/helloworld</url-pattern>
  </servlet-mapping>

</web-app>
```

|項目名|内容|
|:--|:--|
|servlet-name|xml内での紐付けに使うのみ|
|servlet-class|先ほど作成したクラスファイル名「HelloWorld」を書いておく|
|url-pattern|指定した値をもとにURLでアクセスできるようになる|

例えば今回だと、以下のような流れになる。
1. http://localhost:8080/hello/helloworld のURLへアクセスする
2. web.xmlの設定により、HelloWorld.classへアクセス。
3. さきほどHelloWolrd.javaへ記載したhtmlが展開されてレスポンスされる

※最近のフレームワークだと、ここに情報を書かずJavaでアノテーションを使ってURLマッピングしている。

### Tomcat起動、動作確認、終了
ターミナル経由でTomcat起動

```
$cd $CATALINA_HOME/bin
$./startup.sh
```

以下URLへアクセスし、さきほど作成したHelloWorld.javaへ記載したhtmlが表示されればOK
http://localhost:8080/hello/helloworld

ターミナル経由でTomcat終了

```
$cd $CATALINA_HOME/bin
$./startup.sh
```

# 所感
・コンパイルして置き直して起動、という手間がかなり面倒だった。
今回ひとつしかコンパイルしてないのにとても面倒だなと感じた。(慣れたら面倒では無くなるのか？)
自動的にコンパイル（+必要ならば配置)してくれるものが誕生したのも頷ける。