shiba-hiro’s 備忘録

技術ブログの皮を被ったただの備忘録

JavaプログラムをTomcatへデプロイする

前回は、Mavenを用いてJavaの簡単なプログラムを作成し、実行してみました。
今回は、そういったJavaのプログラムをTomcatというサーバーへデプロイし、ごくごく簡素なWeb APIをつくってみます。

shiba-hiro.hatenablog.com

動作確認の準備

初回はVagrantのボックスリストでトップにきていたtrusty64(14.04)のUbuntuを使っていましたが、
今回からはゲストOSのバージョンをxenial64(16.04)へ変更します。
(自分が普段使っているPCのバージョンに合わせたいだけです。。。trustyのままでも操作は大差ありません)
適当なディレクトリを作成し、次のコマンドでVagrantfileを作成します。

$ mkdir ~/SandBox/vagrant-practice/for-tomcat
$ cd ~/SandBox/vagrant-practice/for-tomcat

$ vagrant init ubuntu/xenial64

さらに、効率的に実験を行うために、先んじてVagrantfileへいくつかの設定を追記しておきます。

ひとつめは、ポートのフォワーディングです。
仮想マシン内に立てたサーバーとホスト側とで通信を行うためです。
利用するTomcatは、HTTPのリクエストを8080番ポートで受けるというのがデフォルトの設定になっています。
そこで、ゲストOSの8080番ポートへリクエストを転送できるよう、次のような設定を書き足します。

config.vm.network "forwarded_port", guest: 8080, host: 7878

ふたつめは、共有フォルダの設定です。
今回からはエディターやIDEで編集した各種ファイルを使う前提で進めます。
ファイル共有の方法は、先日のgitを導入した記事でも紹介していますが、ローカルPCで完結することではあるので(かつ今回は共有方法がクリティカルな問題になる内容ではないので)、ホストOSとゲストOSをつなぐ共有ディレクトリを作成してしまいましょう。

今回使う共有用のディレクトリはsharedと名付けて、Vagrantfileと同じ階層へ作成しておきます。

config.vm.synced_folder "./shared", "/home/vagrant/shared", create: true, owner: "vagrant", group: "vagrant"

shiba-hiro.hatenablog.com

設定を更新できたら、 vagrant up仮想マシンを立ち上げます。

次のようなログが流れたのを確認できるはずです。

...
==> default: Forwarding ports...
    default: 8080 (guest) => 7878 (host) (adapter 1)

...
==> default: Mounting shared folders...
default: /home/vagrant/shared => /Users/shiba_hiro/SandBox/vagrant-practice/for-tomcat/shared

また、vagrant sshすると、ホームディレクトリにsharedディレクトリを確認できます。

$ ls
shared

Tomcatのインストールと起動

それではTomcatをインストールしましょう。

$ sudo apt update
$ sudo apt install -y tomcat8

# apt installで取得したアプリは自動で起動するので、
# runningのステータスを確認できる。
# qを入力すると終了できる。
$ sudo service tomcat8 status

Tomcatの起動を確認できたら、早速リクエストを送ってみましょう。
ホストOSのブラウザで下記のURLへアクセスすると、 "It works !"と記載されたページを表示できるはずです。

http://localhost:7878/

静的なページを返す

まずはオリジナルの静的なページを返却させてみましょう。
次のようなHTMLファイルを作成して、sharedディレクトリ経由で仮想マシンに渡します。

  • index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Sample HTML</title>
  </head>
  <body>
    <div class="html-body">

      <main>
        <div>
          <span>simple html document</span>
        </div>
      </main>

    </div>
  </body>
</html>

作成したら、/var/lib/tomcat8/webapps/下に新しくディレクトリを作って、ファイルを配置します。

$ sudo mkdir /var/lib/tomcat8/webapps/sample
$ sudo cp ~/shared/index.html /var/lib/tomcat8/webapps/sample/

配置したら、ホストOSで下記のURLへアクセスすると、作成したhtmlを表示できます。

http://localhost:7878/sample/

こんな感じで、Webサーバー的にTomcatを利用できることが確認できました。

サーブレットを利用してみる

次は、ごくごく簡単なweb apiを作ってみます。
サーブレットと呼ばれるjavaプログラムの仕組みに乗っかって、レスポンスを返すプログラムをTomcat上で動かします。

下記のようなjavaファイルを用意しましょう。

  • SampleAPIController.java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SampleAPIController extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response)
          throws IOException, ServletException {

    response.setContentType("application/json");
    PrintWriter out = response.getWriter();
    out.println(" { \"key\" : \"value\" } ");
    return;
  }
}

doGetはHttpServletが持っているメソッドで、HTTPのGETリクエストに応答します。

javaファイルの作成ができたら、仮想マシン側にJDKをインストールして、クラスファイルを作成します。

$ sudo apt install -y default-jdk

# tomcat付属のライブラリとともにコンパイル
$ javac -cp /usr/share/tomcat8/lib/servlet-api.jar ~/shared/SampleAPIController.java

# sample配下にWEB-INFディレクトリを作成して配置
$ sudo mkdir -p /var/lib/tomcat8/webapps/sample/WEB-INF/classes
$ sudo cp ~/shared/SampleAPIController.class /var/lib/tomcat8/webapps/sample/WEB-INF/classes/

さらに、次のweb.xmlファイルも作成して配置します。
このファイルを置くと、記述に沿って、Tomcatサーブレットを動作させてくれます。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  <servlet>
    <servlet-name>SampleAPIControllerName</servlet-name>
    <servlet-class>SampleAPIController</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>SampleAPIControllerName</servlet-name>
    <url-pattern>/get-api</url-pattern>
  </servlet-mapping>
</web-app>
# web.xmlも、WEB-INF配下へおく
$ sudo cp ~/shared/web.xml /var/lib/tomcat8/webapps/sample/WEB-INF/

ここまでできたら、次のURLへアクセスしてみてください。

http://localhost:7878/sample/get-api

あるいは、curlコマンドでリクエストしても構いません。
いずれにしても、{ "key" : "value" }という表示を返してくれるはずです。

これで、とてもシンプルなものですが、Javaのプログラムをサーバー上で動作させることができるようになりました。

引数を利用できるようにアレンジを加える

せっかくなので、もう少しアレンジを加えてみます。
引数を利用してプログラムを動作させてみましょう。

まずはjavaファイルを、引数を利用するように書き換えて配置しなおします。

  • SampleAPIController.java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SampleAPIController extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response)
          throws IOException, ServletException {
    String arg = System.getProperty("testval");

    response.setContentType("application/json");
    PrintWriter out = response.getWriter();
    out.println(" { \"key\" : \"" + arg + "\" } ");
    return;
  }
}
$ javac -cp /usr/share/tomcat8/lib/servlet-api.jar ~/shared/SampleAPIController.java
$ sudo cp ~/shared/SampleAPIController.class /var/lib/tomcat8/webapps/sample/WEB-INF/classes/SampleAPIController.class 

さらに、setenv.shというファイルを作成して、次のような記述をおきます。

CATALINA_OPTS="-Dtestval=this-is-arg"

作成後は、/usr/share/tomcat8/bin/の下に配置します。
こうすることで、起動時にスクリプトが読み込まれるようになります。

$ sudo cp ~/shared/setenv.sh /usr/share/tomcat8/bin/

では、tomcatを再起動させて、再度get-apiへアクセスしてみましょう。

$ sudo service tomcat8 stop
$ sudo service tomcat8 start

# 仮想マシン内では8080ポートを利用しているので、
# 8080へリクエスト
$ curl http://localhost:8080/sample/get-api
 { "key" : "this-is-arg" }

このように、引数で設定した値を取り出して表示できていたら、実験は成功です。
TomcatJavaプログラムを乗せて動作させる感覚がつかめてきたので、今度はMavenと組み合わせて使ってみます。