Servlet + TomcatでWeb その1
カクカクシカジカで、Java(Servlet)を使ってWebサイトを作ってみることにしました。
ひとまず、これまでSinatraで作っていたものをJava、 Tomcatを使って置き換えてみます。
準備
- Javaのインストール
- Eclipse IDE for Java EE Developersを公式サイトからダウンロードして、任意の場所に展開する(日本語化したい場合はプラグインを入れておく)
- Tomcat8.0を公式サイトからダウンロードして、任意の場所に展開する
※EclipseとTomcatをaptでインストールしないのは、最新バージョンを使いたいということと、EclipseからTomcatを使うときに一般ユーザーの権限では失敗するからです (この辺りの設定もするべきなのでしょうが、今回はスキップします)。
プロジェクトの作成 1. File>Projectから、新規プロジェクト作成のウィザードを開いて、 Web>Dynamic Web Projectを選択してNextをクリック 2. プロジェクト名は任意のものを、「Target runtime」でWebアプリを動かすためのRuntime(今回はTomcat)を選択 3. Step2でRuntimeがない場合、または新規追加したい場合は「New Runtime」をクリック
Runtimeの追加
4. 「Select the type of runtime environment」から追加したいRuntime(今回はTomcat)を選択してNextをクリック 5. 「Tomcat installation directory」で、インストールしたTomcatのディレクトリ直下を指定する 6. 「JRE」で、インストールしたjava(java-8-oracle)を選択して「Finish」をクリック
ここまで
7. Nextをクリックして、「Source folders on build path」は何も追加するものがなければそのままNextをクリック 8. 「Generate web.xml deployment descriptor」にチェックを入れて、web.xmlを自動で作成するようにして「Finish」をクリックServletの追加
web.xml
Tomcatでは使用するServletのURLやTopドメインを開いたときに表示するページ(Welcome file)などを指定する、web.xmlを使用します。
プロジェクトの作成時に「Generate web.xml deployment descriptor」にチェックを入れている場合、 プロジェクトのディレクトリ>WebContents>WEB-INFにweb.xmlが作成されています(そうでない場合は自分で作成・追加します)。
welcome file
以下のようにファイル名を指定することで、Topドメインを開いた時に該当のファイルを表示できます。
< welcome-file-list > < welcome-file >mainpage.html< / welcome-file > < / welcome-file-list >
Viewファイルを設置する
デフォルトではHTMLなどの(MVCにおける)Viewにあたるファイルを置きます。
Eclipseで上記のHTMLを開くと、mainタグでアラートが出ていますが、特に気にしなくても良さそうです(HTML5のタグに対応していないようです)。
Serverの設定
デフォルトではEclipseの画面下部に表示される「Server」に何も表示されていない場合は、右クリック>New>Serverで、Tomcatを追加します。
今回は以下を指定しました。
- Select the server type: Tomcat v8.0 Server
- Server's host name: localhost
- Server name: Tomcat v8.0 Server at localhost
- Server runtime environment: Apache Tomcat v8.0
上記を指定したあとNextをクリックして、「Available」に作成したプロジェクト名が表示されていたら、「Add>」をクリックして「Configured」に移動させます。
実行
とりあえず実行してみます。
Eclipseの画面上部にある「Debug」または「Run」ボタンをクリックして、サーバーを起動します(初回は右隣の▼から実行対象を選ぶ必要があるかもしれません)。
あとは「localhost:8080/jvTabTest」にアクセスすれば、Welcome fileで設定したmainpage.htmlが表示されるはずです。
JavascriptやCSSのパスは、HTMLのパス(WebContent直下?)からの相対パスで指定できます。
Servletを使う
Sinatraでのapp.rb(この辺参照)のように、ユーザーがアクセスしたURLを振り分けて、何らかの処理をしたりページを表示するControllerを作成してみます。
上記で作成したServletは、プロジェクト>src>controllerにあります(Controllerは作成時に設定したJava package名です)。
デフォルトでは以下のような内容です
TabController.java
package controller; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/TabController") public class TabController extends HttpServlet { private static final long serialVersionUID = 1L; public TabController() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Getリクエストが送信されたら実行 } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Postリクエストが送信されたら実行 } }
@WebServletで設定したURL(ここでは「localhost:8080/jvTabTest/TabController」)にアクセスした時に、このServletが実行されます。
JavaScriptから「localhost:8080/jvTabTest/contents」にGetリクエストを投げたときに、HTMLのファイルを返すようにしたいので、以下のように変更します。
@WebServlet("/contents")
また、HTMLのファイルを返すメソッドはdoGet()に記述します。
ServletでHTMLファイルをロードし、中身を返す
※正直実用的ではない気がするのですが、メモとして残しておきます。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // エンコーディングの指定. request.setCharacterEncoding("UTF-8"); // JavaScriptから「cnt=0」のように渡されるパラメータを取得. Enumerationnames = request.getParameterNames(); String strContent = ""; String strGotResult = ""; if (names.hasMoreElements()){ strContent = (String)request.getParameter(names.nextElement()); // 取得したパラメータから、HTMLファイルのパスを取得する. String strCntFilePath = this.getServletContext().getRealPath("/contents/" + strContent + ".html"); // 取得したパスからファイルを取得する. File file = new File(strCntFilePath); char data[] = new char[3000]; FileReader filereader = new FileReader(file); // ファイルの内容を読み込む. int charscount = filereader.read(data); strGotResult = new String(data,0,charscount); // ファイルリーダーを閉じる filereader.close(); } // 戻り値の内容をHTMLに設定して、読み込んだ内容を返す. response.setContentType("text/html"); response.getWriter().write(strGotResult); }
内容はコメントの通りなのですが、読み込んだHTMLファイルに手を加えるわけでもないため、ファイルをServletでは読み込まず、 そのままHTMLとして渡す方法がないか、と思案中です。
- JavaScriptから直接HTMLファイルを取得できるのですが、ファイルのパスを直接読み込まない方が良いかと思い、別の方法を探っています。
- HTMLではなくJavaの文字列型としてファイルの中身をもたせれば解決はしますが、メンテナンスなどを考えるとこれも不便かなと。
次回に続きます。