以前、 Eclipseを使ってTomcat+JSP+Servlet+MySQLでメモアプリ作成で「Tomcatプロジェクト」でwebアプリのプロジェクトを作成したが、Mavenプロジェクトでアーキタイプにmaven-archetype-webapp
を選択してプロジェクトを作ったほうが良い、ということで作ってみた。
参考: EclipseでサーバサイドJavaを作るときのプロジェクトとwarファイルのエクスポート
プロジェクト設定
maven-archtype-webappプロジェクト作成
「Mavenプロジェクト」を選択
「シンプルなプロジェクトの作成(S)」のチェックを__外して__「次へ」
アーキタイプは「maven-archtype-webapp」を選択
ディレクトリ構成
初期状態
作成直後のプロジェクト構成は、ソースファイル用のディレクトリのsrc/main/java
とsrc/test/java
が欠落しているため、これは新規作成メニューのフォルダや、エクスプローラなどから手動で作成する。
(これはなぜかエラーとして出力されない)
Javaバージョン設定
EclipseでMavenプロジェクトを作るとJava1.5設定になるのは仕様なんかな。。
システムライブラリ
「JREシステムライブラリー」のところが「J2SE-1.5」になっているので、右クリックのプロパティーから、「JavaSE-1.8 (java8)」を選択
プロジェクト・ファセット
すると今度は「Javaプロジェクト・ファセットのバージョンと一致しません」というエラーが出るので
プロジェクトのプロパティを開き「プロジェクト・ファセット」からバージョンを1.8に設定する
Mavenのコンパイラバージョン
EclipseでのJDKバージョンと別に、mavenビルドを行う際のコンパイラバージョンを指定する。
ルート要素の<project>
直下に以下が記述される。(手書きで入れてもよい)
<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>
の部分へコピーする
<!-- 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
にコピペ
これでファイルを保存すると、ファイルの内容に従ってservlet-apiのダウンロードとプロジェクトへの組み込みが自動で行われる。
処理が正常に完了すれば、HttpServlet
がビルドパスに見つからないエラーが解消される。
JSPの表示
この時点でプロジェクトの右クリックメニューの「実行(R)」->「サーバーで実行」からTomcatを選択、サーバー上で構成するリソースに対象プロジェクトが含まれていることを確認して実行すれば、プロジェクト作成時に含まれていたindex.jsp
の内容がブラウザで表示できる
ただし、jspファイルをブラウザから直接アクセスする場所に構成するのは好ましくないため、src/main/webapp/WEB-INF
以下の任意のパス(WEB-INF/jsp
など)へ移動し、直接のアクセスをできなくし、サーブレット経由で表示するようにする。
Servletの作成と表示
新規作成メニューの「サーブレット」から。
パッケージ名とクラス名を入力したあと、メタ情報も入力できる。
どのメソッドをオーバーライドするかの選択
ここで入力したメタ情報の値はsrc/main/webapp/WEB-INF/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>
<!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を起動(あるいは再起動)すれば、自動生成されたコードの内容で実行される
ServletからJSPの呼び出し
Tomcatプロジェクトの場合と同じ。
/WEB-INF/jsp/main.jsp
のjspファイルに対し、サーブレットのdoGet()
で以下のように書けば表示される
String path = "/WEB-INF/jsp/main.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(path);
dispatcher.forward(request, response);
maven installとwarファイル
「実行(R)」->「Maven install」を実行することで、target
ディレクトリ直下にwarファイルが生成される
「Maven clean」を実行すればビルド結果はすべて消去される
エクスポートによるwarファイル作成
プロジェクトメニューの「エクスポート」でもwarファイル作成ができる
この場合はMavenに関係なく作成でき、任意のパスに出力できる。