HerokuへシンプルなJava Servletアプリをデプロイする方法

##HerokuへシンプルなJavaアプリをデプロイする
Java Servletの開発について最近勉強し、ローカル環境でいくつかシンプルなアプリなどを作って試したあとに、これをサーバにあげてみたいなと思ったのですが、数多くのブログ記事や解説はMavenやGradleなどを使ったアプリについての記事が多く、簡単なServletアプリをデプロイしたいだけの際はどうやるのかがわからずに困ったので、備忘録がてら自分で書いてみました。

#1.Servletアプリをwarファイル形式でエクスポートしておく

Eclipse環境であれば、動的プロジェクトファイルを右クリックメニューでエクスポートを選択し、Warファイルでエクスポートする。

![スクリーンショット 2020-07-18 12.29.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485150/82044372-9aa8-beb0-b842-891b2cccba9e.png)

エクスポート先を宛先で選んで、任意のディレクトリにエクスポート。

#2.CLIでHerokuにログインする

Heroku CLIについてはあらかじめインストールなどしておくことを前提にしています。
インストールについては[こちら](https://devcenter.heroku.com/articles/getting-started-with-java#set-up)

```
$ heroku login
```

#3.HerokuにアプリをCreateする

これはCLIでもHerokuのWebアプリケーション上からでもどちらでも良いと思います。

![スクリーンショット 2020-07-18 12.37.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485150/45368e84-3740-7a9b-b0ba-3b54796e1b9a.png)

Web上から作成する場合は、Dashboardの右上NewボタンからAppが作成できます。

#4.HerokuのJava用プラグインのインストール

WarファイルにてServletアプリをデプロイしたい場合は、このCLIをダウンロードしておきます。

```
$ heroku plugins:install java
```

#5.Servletアプリをデプロイする

以下コマンドを打ちこみます。

```
$ heroku war:deploy <warファイルへのダイレクトパス> --app <先ほど作成したHerokuのアプリ名>
```

以下のような結果が出てきます。

```
8.5.57/webapps/App/ShoppingCart.war --app shoppingcartjava
 ›   Warning: heroku update available from 7.35.1 to 7.42.4.
Uploading ShoppingCart.war
-----> Packaging application...
       - app: shoppingcartjava
       - including: webapp-runner.jar
       - including: ShoppingCart.war
-----> Creating build...
       - file: slug.tgz
       - size: 21MB
-----> Uploading build...
       - success
-----> Deploying...
remote: 
remote: -----> heroku-deploy app detected
remote: -----> Installing JDK 1.8... done
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote: 
remote: -----> Compressing...
remote:        Done: 72.3M
remote: -----> Launching...
remote:        Released v3
remote:        https://shoppingcartjava.herokuapp.com/ deployed to Heroku
remote: 
-----> Done

```

https://shoppingcartjava.herokuapp.com/ がアプリのデプロイ先になります。


![スクリーンショット 2020-07-18 12.46.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485150/aabdfe4d-095e-a356-6367-9edf913d939a.png)

表示されました！

参考記事は以下Herokuの公式Docです。
https://devcenter.heroku.com/articles/war-deployment

##補足: Eclipseから実行する際に設定していたパスはローカル以外のサーバ上では使えない

ちなみにただ単に上記でサーバへアップロードしたアプリはログインしようとしたところ、404エラーが出てしまいました。

![スクリーンショット 2020-07-20 20.46.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485150/c3bfa4b7-cf85-811f-96f6-e6da8475e2cb.png)

Login画面が見つからないようです。このときの`web.xml`およびトップ画面である`index.jsp`のコードは以下の通り。

`web.xml`

```
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>ShoppingCart</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>Login</display-name>
    <servlet-name>Login</servlet-name>
    <servlet-class>servlet.Login</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Login</servlet-name>
    <url-pattern>/Login</url-pattern>
  </servlet-mapping>
  <servlet>
    <description></description>
    <display-name>ShopMain</display-name>
    <servlet-name>ShopMain</servlet-name>
    <servlet-class>servlet.ShopMain</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ShopMain</servlet-name>
    <url-pattern>/ShopMain</url-pattern>
  </servlet-mapping>
</web-app>
```

`index.jsp`

```
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>ショッピングサイトへようこそ</h1>
<p>ログインメニュー</p>
<form action="/ShoppingCart/Login" method="post">
<label for="userName">ユーザ名: </label><input type="text" name="userName">
<label for="pass">パスワード: </label><input type="text" name="pass">
<input type="submit" value="submit">
</form>
</body>
</html>
```

ここでの原因は、`index.jsp`では`/ShoppingCart/Login`というパスでサーブレットクラスへのパスを指定していたのですが(Eclipseからローカルサーバーで行う場合には問題なし)、ローカル以外のサーバで同様のパスでのアクセスを実現したい場合、パスが変わるため、`web.xml`を以下のように変更するか、`index.jsp`のform action先パスを`/Login`と変更する必要があります。

`web.xml`

```
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>ShoppingCart</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>Login</display-name>
    <servlet-name>Login</servlet-name>
    <servlet-class>servlet.Login</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Login</servlet-name>
    <url-pattern>/ShoppingCart/Login</url-pattern>
  </servlet-mapping>
  <servlet>
    <description></description>
    <display-name>ShopMain</display-name>
    <servlet-name>ShopMain</servlet-name>
    <servlet-class>servlet.ShopMain</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ShopMain</servlet-name>
    <url-pattern>/ShoppingCart/ShopMain</url-pattern>
  </servlet-mapping>
</web-app>
```