サーブレットとは
動的なWebページを作る、サーバー側に配置されるJavaアプリケーションの一つです。
サーブレットの開始点
スタンドアローンのJavaアプリケーションはmainメソッドが処理開始点ですが、WebアプリケーションではWebクライアント(ブラウザ)からのリクエストはWebサーバーに導入されたWebコンテナが受けてJSPやサーブレットを実行します。従ってユーザアプリケーションの開始点はmainメソッドの代わりのdoGetメソッド、またはdoPostメソッドになります。
サーブレットとWebクライアントはどのように繋がるのか
doGetメソッドもdoPostメソッドもWebクライアントからのリクエストをHttpServletRequestオブジェクトで受け取り、レスポンスをHttpServletResponseオブジェクトを使って返します。これらのオブジェクトはdoGetメソッド(doPostメソッド)の引数としてWebコンテナとの間で受け渡されます。
サーブレットのテンプレート
package com.example; 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 XXXXXXXXXX extends HttpServlet { @Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("Windows-31J"); String message = req.getParameter("xxxx"); resp.setContentType("text/html; charset=UTF-8"); PrintWriter out = resp.getWriter(); out.println("<html><head><title>〇〇〇〇</title></head><body>"); out.println("<p>" + (出力情報) + "</p>"); out.println("</body></html>"); } }
サーブレットの中はどうなっている
doGetメソッドの中では、まずsetContentTypeメソッドを使ってレスポンスとして返すコンテンツのメディアタイプ(text/html)と文字コード(charset)を設定します。
次にgetWriterメソッドを使ってPrintWriterオブジェクトを取得し、レスポンスとなるhtmlコードを書き込みます。
サーブレットはどこに置く
サーブレットの実行はWebコンテナが行うので、完成したサーブレットはWebコンテナが指定する場所に置く必要があります。Tomcatの場合はWebappsフォルダーの下に任意のフォルダーを作ると、それがWebアップリケ―ションのルートディレクトリ(コンテキストルート)となり、localhost:8080/XXXXのXXXXとして指定流ることが出来ます。
そして、コンテキストルートにはWEB=INFフォルダー及びその直下にclassesフォルダーを作る決まりになっていて、そのclassesフォルダーの中にサーブレットを配置します。ここでサーブレットのクラスファイルがpackageに組み込まれて入れば(例えばcom.svlet)、classesホルダーの下にcomフォルダー、その下にsvletホルダーを作って、その中にサーブレットのクラスファイルを配置します。
サーブレットをどう呼ぶのか
サーブレットが実際に配置されているフォルダーを、クライアントが直接アクセスできるとサーバーにとっては無防備すぎます。
そこでWebコンテナはクライアントにはコンテキストルートまでを公開し、それ以下のパスにアクセス出来ないようにしています。実際のパスを公開する代わりに、コンテキストルートに続けて疑似的なパスを設定し、そのパスと実際のサーブレットの配置場所をマッピングする配備記述子(ディプロイメントディスクリプタ)と呼ばれるXML形式のファイルを介して、クライアントには疑似的なパスを公開しています。
配備記述子(ディプロイメントディスクリプタ)とは
コンテキストルート以下のWEB-INF/classesを省きサーブレットの(packageを含んだ)クラスファイル名とサーブレットの実際の配置パス名をマッピング(紐付け)するxml形式のファイル。このファイルは名前をweb.xmlとして、WEB-INFフォルダーに配置します。
「wheb.xmlの型式」 <?xml version="1.0" encoding="Windows-31J"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <description> <!-- 省略可 --> Servlet Examples. </description> <display-name> <!-- 省略可 --> My First Servlet </display-name> <!-- servletのクラスに名前を設定する --> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.getParam.MyFirstServlet</servlet-class> </servlet> <!-- servletとURLパターンを関連付ける --> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <!-- 以下同じclassesフォルダーに配置するサーブレットごとにマッピング情報を書く --> </web-app>
必要な記述は<servlet>と<servlet-mapping>
<servlet>では<servlet-class>でサーブレットのクラス名、パケージに属する場合はパケージ名も含めて記述する。
<servlet-mapping>では<url-pattern>でサーブレットをWebクライアントから呼ぶ(action=”xxxx”)疑似URLを「/」付きで記述する。
両者を紐付ける名前を<servlet-name>に記述する。
※配備記述子はコンテキストルート毎に在っても良いが、servlet-nameはwebapps以下でユニークでなければいけない。
※サーブレットをコンパイルしなおしたら、Tomcatは一旦停止し、再起動する。起動のタイミングでサーブレットのclassファイルがキャッシュされるため。