第3章 サーブレットの基本
サーブレットの基本
homepage
# **サーブレットの基本** *** ## **1.Webアプリケーションの設定** ### **1-1.基本パッケージ** サーブレットを作成する上で必要となるクラスが含まれているパッケージについて簡単に見ていきます。大きくわけて2つのパッケージが用意されており、「**javax.servlet**」パッケージと 「**javax.servlet.http**」パッケージとなります。 <br><br> ### **1-2.HttpServletクラスのメソッド** 「HttpServlet」クラスでは多くのメソッドが定義されています。リクエストのHTTPメソッドの種類毎に対応するメソッドがそれぞれ用意されています。 <table border="1"> <tr style="width:600px ;background-color:#C6E0B4 ;text-align:center;"> <th>リクエストメソッド</th><th>サーブレットメソッド</th><th>機能</th> </tr> <tr> <td>GET</td><td>doGet(HttpServletRequest req, HttpServletResponse resp)</td> <td>コンテンツの取得、情報の送信</td> </tr> <tr> <td>POST</td><td>doPost(HttpServletRequest req, HttpServletResponse resp)</td> <td>情報の送信</td> </tr> <tr> <td>PUT</td><td>doPut(HttpServletRequest req, HttpServletResponse resp)</td> <td>コンテンツの作成と更新</td> </tr> <tr> <td>DELETE</td><td>doDelete(HttpServletRequest req, HttpServletResponse resp)</td> <td>コンテンツの削除</td> </tr> <tr> <td>HEAD</td><td>doHead(HttpServletRequest req, HttpServletResponse resp)</td> <td>ヘッダ部分の取得</td> </tr> <tr> <td>TRACE</td><td>doTrace(HttpServletRequest req, HttpServletResponse resp)</td> <td>ループバックの起動</td> </tr> <tr> <td>OPTIONS</td><td>doOptions(HttpServletRequest req, HttpServletResponse resp)</td> <td>オプションの一覧を取得</td> </tr> </table> <br> 「HttpServlet」クラスを継承したクラスは、このどれかのメソッドを最低1つは実装する必要があります。もし複数のHTTPメソッドで呼び出される可能性がある場合は複数のメソッドを実装することも可能です。<br> HTTPメソッドの中でも主に使われるのは「GET」と「POST」です。サーバレット開発する際には、doGetかdoPostのいずれかをオーバーライドします。 **・「doGet」メソッド:** <br> ``` protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException ``` 「GET」メソッドはクライアントからページの要求を行う場合に使われます。 * 直接サーブレット名をURLに指定して表示したり、**リンク**に設定されたサーブレットをクリックした場合には「GET」を使ってリクエストが来ます。 * またフォームにおいて送信方法に「GET」を使った場合にも「GET」メソッドが使われます。<br> **・「doPost」メソッド:** ``` protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException ``` 「POST」メソッドはクライアントからデータを送る場合に使われます。 * 主にフォームにおいて送信方法に「POST」を指定した場合に使われます。<br> ここではサーブレットの基本となるものを順に作っていきたいと思います。<br> <br><br> ### **1-3.HttpServletクラスの継承<br>** HTTP通信を行うサーブレットは「HttpServlet」クラスを継承して作成します。 ``` public class HelloWorld extends HttpServlet{ /* ... */ } ``` **・HTTPメソッドに対応したメソッドの実装<br>** 「HttpServlet」クラスを継承した場合は、「doGet」メソッド又は「doPost」メソッドを実装します。例えばGETメソッドで呼ばれる可能性があるサーブレットであれば次のようになります。 ``` public class HelloWorld extends HttpServlet{ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ /* ... */ } } ``` POSTメソッドで呼ばれる可能性があるサーブレットであれば次のようになります。 ``` public class HelloWorld extends HttpServlet{ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ /* ... */ } } ``` GETメソッドとPOSTメソッドの両方で呼ばれる可能性があるサーブレットであれば次のようになります。 ``` public class HelloWorld extends HttpServlet{ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ /* ... */ } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ /* ... */ } } ``` 作成したサーブレットをブラウザなどから呼び出した時にGETメソッドで呼び出せば「doGet」メソッドの中に記述した処理が実行され、フォームなどから「POST」メソッドを使ってデータを送信した場合は「doPost」メソッドの中に記述した処理が実行されます。<br> **・doGetメソッドとdoPostメソッド** サーブレットが呼ばれた時に「doGet」メソッドと「doPost」メソッドが呼ばれるの様子を実際に確認してみます。 次のような簡単なサーブレットを用意しました。 #### **例** [Sample3_1.java] ``` package hello; import java.io.IOException; import java.io.PrintWriter; 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("/Sample3_1") public class Sample3_1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println(createHTML("GET")); out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println(createHTML("POST")); out.close(); } protected String createHTML(String methodType) { StringBuffer sb = new StringBuffer(); sb.append("<html>"); sb.append("<head>"); sb.append("<title>サンプル</title>"); sb.append("</head>"); sb.append("<body>"); sb.append("<p>"); sb.append(methodType); sb.append("メソッドで呼び出されました</p>"); sb.append("<p><a href=\"Sample3_1\">リンク</a></p>"); sb.append("<form action=\" Sample3_1\" method=\"get\">"); sb.append("<input type=\"submit\" value=\"GETで送信\">"); sb.append("</form>"); sb.append("<form action=\"Sample3_1\" method=\"post\">"); sb.append("<input type=\"submit\" value=\"POSTで送信\">"); sb.append("</form>"); sb.append("</body>"); sb.append("</html>"); return (new String(sb)); } } ``` #### **実行結果** <!--graph3-1.png --> <img src="https://i.loli.net/2019/06/27/5d1473c35711919925.png"/> ## **2.サーブレットのライフサイクルとインスタンス変数** サーブレットはTomcatなどのサーブレットが動作するコンテナが起動してから最初にサーブレットが呼ばれたときにコンテナにロードされインスタンスが作成されます。<br> サーブレットはリクエストに対してスレッドを作成し、そのスレッドが実際の処理を行います。複数のリクエストが同時にあればそれぞれ別のスレッドが用意されマルチスレッドで動作することになります。スレッドはリクエストに対する処理が終われば終了しますがインスタンスはそのまま残っており新しいリクエストが来れば新しいスレッドを作成して実行します。そのため2回目以降はインスタンスを作成する時間がかかりません。<br> コンテナが終了一定時間サーブレットに対してアクセスが無かった場合にインスタンスは破棄されます。<br> ### **2-1.インスタンス変数を用いたサンプル** サーブレットはリクエストがあるたびにスレッドが用意されて実行されますが、インスタンスに含まれるスレッドで共有される変数を作成することが出来ます。これがインスタンス変数です。 #### **例** [Sample3_2.java] ``` package hello; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; @WebServlet("/Sample3_2") public class Sample3_2 extends HttpServlet { int count = 0; public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); StringBuffer sb = new StringBuffer(); sb.append("<html>"); sb.append("<head>"); sb.append("<title>サンプル</title>"); sb.append("</head>"); sb.append("<body>"); count++; sb.append("<p>訪問人数:"); sb.append(count); sb.append("</p>"); sb.append("</body>"); sb.append("</html>"); out.println(new String(sb)); out.close(); } } ``` #### **実行結果** <!--graph3-2.png --> <img src="https://i.loli.net/2019/06/27/5d1474958ed7c68539.png" /> <br> ### **2-2.サーブレットのライフサイクル**  **(1)initメソッド** インスタンスが作成された後で実際の処理が行われる前に呼び出されるのが「init」メソッドです。(「init」メソッド内にローカルの初期化処理を記述してもインスタンスの初回作成時にしか実行されませんので注意して下さい)。 実際の使い方としては次のような感じとなります。 ``` import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Sample extends HttpServlet { public void init() throws ServletException{ /* 初期化処理 */ } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ /* ... */ } } ``` 「init」メソッドはインスタンス作成後に一度だけ呼ばれるメソッドですので、インスタンス変数の初期化などに利用します。 **(2)destroyメソッド** サーブレットが破棄される前に呼び出されるのが「destroy」メソッドです。インスタンス変数の値をファイルに書き出したり、インスタンスで共有していたデータベース接続の切断処理を行ったりといった処理を行うのに使います。 「destroy」メソッドは「HttpServlet」クラスの親クラスである「GenericServlet」クラスで定義されています。 ``` import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Sample extends HttpServlet { public void init() throws ServletException{ /* 初期化処理 */ } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ /* ... */ } public void destroy(){ /* 終了処理 */ } } ``` #### **例** [Sample3_3.java] ``` package hello; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; @WebServlet("/Sample3_3") public class Sample3_3 extends HttpServlet { int count; public void init() throws ServletException{ count = 100; log("カウント開始します"); } public void destroy(){ log("カウントの最終値は" + count + "でした"); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html; charset=Utf-8"); PrintWriter out = response.getWriter(); StringBuffer sb = new StringBuffer(); sb.append("<html>"); sb.append("<head>"); sb.append("<title>サンプル</title>"); sb.append("</head>"); sb.append("<body>"); count++; sb.append("<p>訪問人数:"); sb.append(count); sb.append("</p>"); sb.append("</body>"); sb.append("</html>"); out.println(new String(sb)); out.close(); } } ``` #### **実行結果** <!--graph3-4.png --> <img src="https://i.loli.net/2019/06/27/5d1475d34621372071.png"/>
content
戻る