最終更新日:190316原本2018-12-23 

[Eclipse/Tomcat] Mavenのwebappプロジェクトで Servlet+JSP

以前、 Eclipseを使ってTomcat+JSP+Servlet+MySQLでメモアプリ作成で「Tomcatプロジェクト」でwebアプリのプロジェクトを作成したが、Mavenプロジェクトでアーキタイプにmaven-archetype-webappを選択してプロジェクトを作ったほうが良い、ということで作ってみた。

参考: EclipseでサーバサイドJavaを作るときのプロジェクトとwarファイルのエクスポート

プロジェクト設定

maven-archtype-webappプロジェクト作成

「Mavenプロジェクト」を選択

image.png

「シンプルなプロジェクトの作成(S)」のチェックを外して「次へ」

image.png

アーキタイプは「maven-archtype-webapp」を選択

image.png

image.png

ディレクトリ構成

初期状態

image.png

作成直後のプロジェクト構成は、ソースファイル用のディレクトリのsrc/main/javasrc/test/javaが欠落しているため、これは新規作成メニューのフォルダや、エクスプローラなどから手動で作成する。

image.png

(これはなぜかエラーとして出力されない)

Javaバージョン設定

EclipseでMavenプロジェクトを作るとJava1.5設定になるのは仕様なんかな。。

システムライブラリ

「JREシステムライブラリー」のところが「J2SE-1.5」になっているので、右クリックのプロパティーから、「JavaSE-1.8 (java8)」を選択

image.png

プロジェクト・ファセット

すると今度は「Javaプロジェクト・ファセットのバージョンと一致しません」というエラーが出るので

image.png

プロジェクトのプロパティを開き「プロジェクト・ファセット」からバージョンを1.8に設定する

image.png

Mavenのコンパイラバージョン

EclipseでのJDKバージョンと別に、mavenビルドを行う際のコンパイラバージョンを指定する。

image.png

ルート要素の<project>直下に以下が記述される。(手書きで入れてもよい)

pom.xml
 <properties>
  <java.version>1.8</java.version>
  <maven.compiler.source>1.8</maven.compiler.source>
  <maven.compiler.target>1.8</maven.compiler.target>
 </properties>

これがないと例えばコレクションを使用したソースコードは1.5バージョンのコンパイラが対応していないためエラーとなる。

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.395 s
[INFO] Finished at: 2018-12-23T16:03:11+09:00
[INFO] Final Memory: 9M/245M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project memoapp2: Compilation failure
[ERROR] /C:/Users/zaki/src/java-study/memoapp2/src/main/java/jp/example/www/MainServlet.java:[30,51] ダイヤモンド演算子は-source 1.5でサポートされていません
[ERROR] (ダイヤモンド演算子を使用可能にするには、-source 7以降を使用してください)
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

MavenでServletのjarを組み込む

「スーパークラス "javax.servlet.http.HttpServlet" が Java ビルド・パスで見つかりませんでした」というエラーが(最初から)出ているが、これはServlet関連のライブラリがプロジェクトで参照できていないため。

Mavenを使って設定する。

設定するのは Java Servlet API のjarファイル。
リンク先から2018.12時点で最新のJava Servlet API 4.0.1をプロジェクトに取り込むには、Mavenタブに表示されているXMLの内容をpom.xml<dependencies> ~ </dependencies>の部分へコピーする

image.png

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

この内容を、プロジェクトのpom.xmlにコピペ

image.png

これでファイルを保存すると、ファイルの内容に従ってservlet-apiのダウンロードとプロジェクトへの組み込みが自動で行われる。

処理が正常に完了すれば、HttpServletがビルドパスに見つからないエラーが解消される。

JSPの表示

この時点でプロジェクトの右クリックメニューの「実行(R)」->「サーバーで実行」からTomcatを選択、サーバー上で構成するリソースに対象プロジェクトが含まれていることを確認して実行すれば、プロジェクト作成時に含まれていたindex.jspの内容がブラウザで表示できる

image.png

image.png

image.png

ただし、jspファイルをブラウザから直接アクセスする場所に構成するのは好ましくないため、src/main/webapp/WEB-INF以下の任意のパス(WEB-INF/jspなど)へ移動し、直接のアクセスをできなくし、サーブレット経由で表示するようにする。

Servletの作成と表示

新規作成メニューの「サーブレット」から。

image.png

image.png

パッケージ名とクラス名を入力したあと、メタ情報も入力できる。

image.png

どのメソッドをオーバーライドするかの選択

image.png

ここで入力したメタ情報の値はsrc/main/webapp/WEB-INF/web.xmlにも反映される

web.xml(初期値)
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>
web.xml(追加後)
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>MainServlet</servlet-name>
    <display-name>MainServlet</display-name>
    <description>メイン画面</description>
    <servlet-class>jp.example.www.MainServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern>/MainServlet</url-pattern>
  </servlet-mapping>
</web-app>

Servletのソースは指定したメソッドがオーバーライドされた状態で作成される。

package jp.example.www;

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

/**
 * Servlet implementation class MainServlet
 */
public class MainServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public MainServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().append("webapp-maven! Served at: ").append(request.getContextPath());
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

作成直後の状態でも「実行(R)」->「サーバーで実行」でTomcatを起動(あるいは再起動)すれば、自動生成されたコードの内容で実行される

image.png

ServletからJSPの呼び出し

Tomcatプロジェクトの場合と同じ。

/WEB-INF/main.jspのjspファイルに対し、サーブレットのdoGet()で以下のように書けば表示される

        String path = "/WEB-INF/main.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(path);
        dispatcher.forward(request, response);

maven installとwarファイル

「実行(R)」->「Maven install」を実行することで、targetディレクトリ直下にwarファイルが生成される

http://localhost:8080/memoapp2/MainServlet で main.jsp が実行され、Hello World! が表示される。

image.png

「Maven clean」を実行すればビルド結果はすべて消去される

エクスポートによるwarファイル作成

プロジェクトメニューの「エクスポート」でもwarファイル作成ができる

image.png

この場合はMavenに関係なく作成でき、任意のパスに出力できる。