Servletの作成

概要

Hello World! - 詳細

毎度おなじみ(?)の「Hello World!」をサーブレットで表示することにより、サーブレットの基礎を理解します。

doGet()とdoPost() - 詳細

doGet()メソッドとdoPost()メソッドの役割について理解します。

リクエストパラメータの取得 - 詳細

リクエストパラメータの取得方法について理解します。

全角文字を含むパラメータの取得 - 詳細

全角文字を含むパラメータを、文字化けしないように取得する方法について理解します。

特殊文字のエスケープ - 詳細

特殊文字をエスケープする必要性と、その方法を理解します。

他の画面の呼び出し - 詳細

他の画面を呼び出す3つの方法と、それぞれの用途について理解します。

画面間の情報の共有 - 詳細

画面間で情報を共有する3つの方法と、それぞれの用途について理解します。

サーブレットの初期化・終了処理 - 詳細

Webアプリケーションの定義ファイルの書き方と、サーブレットの初期化・終了処理について理解します。

Cookieの読み書き - 詳細

サーブレットでCookieを扱う方法を理解します。

バイナリデータの出力 - 詳細

サーブレットを使ってバイナリデータを出力する方法を理解します。

総合課題 - 詳細

今までに出てきた知識を活用して、簡単なアプリケーションを作成します。

詳細

Hello World!

以下に、「Hello World!」と表示するだけのサーブレット「HelloWorldServlet?」のソースを示します。
サンプルソース:HelloWorldServlet?.java

package sample.servlet;

//==========================================================
//import

//J2SE
import java.io.*;

//J2EE
import javax.servlet.*;
import javax.servlet.http.*;

/**
 * 「Hello World!」と表示するサーブレット。<br>
 */
public class HelloWorldServlet extends HttpServlet // ・・・1
{
    // ==========================================================
    // メソッド

    // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
    // オーバーライドするメソッド

    /**
     * service()メソッドです。<br>
     * サーブレットは、このメソッドをオーバーライドすることによって処理を行います。<br>
     * このクラスでは、「Hello World!」と表示するHTMLの出力のみを行います。<br>
     * 
     * @param req
     *            リクエスト
     * @param res
     *            レスポンス
     * @exception ServletException
     *                サーブレット例外
     * @exception IOException
     *                入出力例外
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException // ・・・2
    {
        // ContentTypeの設定 ・・・3
        res.setContentType("text/html; charset=Windows-31J");

        // レスポンスからPrintWriterを取得 ・・・4
        PrintWriter out = res.getWriter();

        // HTMLの出力 ・・・5
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Hello World!</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>Hello World!</h1>");
        out.println("</body>");
        out.println("</html>");
    }

}

ポイントを整理すると、次のようになります。

  1. 「javax.servlet.http.HttpServlet?」クラスを継承する。
    1. 「java.io」, 「javax.servlet」, 「javax.servlet.http」パッケージは頻繁に使用するので、importしておいた方が良いでしょう。
  2. service()メソッドをオーバーライドする。
    1. 場合によっては、service()メソッドでなく、doGet()メソッドやdoPost()メソッドをオーバーライドすることもあります。
      詳細については、doGet()とdoPost()を参照して下さい。
  3. レスポンスにContentType?にタイプと文字コードを設定する。
    1. この設定を行わないと、全角文字を出力すると文字化けします。
    2. この設定を変更することで、HTMLだけでなく画像データをバイナリで出力したりすることもできます。
  4. レスポンスからPrintWriter?を取得する。
  5. PrintWriter?を使ってHTMLを出力する。
 
  • リクエストクラスとレスポンスクラス
    サーブレットでのブラウザとのやり取りは、リクエストクラス(javax.servlet.http.HttpServletRequest?)とレスポンスクラス(javax.servlet.http.HttpServletResponse?)を使って行います。
    リクエストクラスの役割は、ブラウザからの入力情報の受け取りです。
    フォームの入力パラメーター, クッキー情報, ヘッダ情報などを取得することができます。
    一方、レスポンスクラスの役割は、ブラウザへの結果の出力です。
    この2つのクラスは頻繁に使用することになりますので、よく覚えておいて下さい。
     
  • 重要
    サーブレットでは、絶対にフィールドは使わないようにしましょう。
    理由は、サーブレットはマルチスレッドで実行されるからなのですが、完全に理解するのは難しいので詳しくは説明しません。
    とにかく、「サーブレットではフィールドは使えない」と覚えておいて下さい。
    (ただし、定数は使用しても構いません。)
    • setContentType?()に「シフトJIS」を文字コードとして指定したい場合は、「Shift_JIS」は使用せずに「Windows-31J」や「SJIS」を使用して下さい。
      これは、「Shift_JIS」のエイリアスがJDKのバージョンによって異なるからです。
      なお、「Windows-31J」や「SJIS」はよく似ていますが別の文字集合で、次のような違いがあります。(「Windows-31J」と「MS932」は同じです。)
      • 収録されている文字が異なります。たとえば、「Windows-31J」はNEC特殊文字,IBM特殊文字を含んでいますが、「SJIS」は含んでいません。
      • 「Windows-31J」は,MS-DOSにおけるNECやIBMの拡張した文字群を収録していますが、一部の重複している文字は、Unicodeの同じコードポイントに割り当てられています。このために、一度読み込んでUnicodeに変換してしまうと、元のファイルに戻すことができないことがあります。
      • 一部の文字に対して、Unicodeに変換する際のコードポイントが違います(~, ∥, -, ¢, £, ¬など)。
        (この問題についての詳細は、http://www.ingrid.org/java/i18n/encoding/shift_jis.htmlを参照して下さい。)
    • サーブレットでは、HTMLのMETA要素で文字コードの指定を行うとかえって文字化けの原因となりますので、使わないようにしましょう。
      (この問題についての詳細は、http://www.ingrid.org/java/jserv/i18n/corruptedchar.htmlを参照して下さい。)
       
  • 課題
    上の例では、「Hello World!」と固定で出力するだけなので面白みがありませんし、それだけの機能を実現するならHTMLで十分です。
    そこで、プログラムらしくこのような九九の表を作成するサーブレット「KukuServlet?」を作成して下さい。
     

doGet()とdoPost()

GETメソッドとPOSTメソッド
サーバーがクライアント(ブラウザ)からパラメータを受け取る方法として、GETメソッドとPOSTメソッドがあります。 (他にもありますが、この二つを理解できれば十分です。)
  • GETメソッド
    通常のリンクなどで使用される送信方法です。
    ブラウザのURLや<a>タグなどのURLに後にパラメータとパラメータ値を設定します。
    文字数制限(256文字程度、ブラウザによって異なる)があるので、あまり大きなデータを送ることはできません。
    (例)
    http://localhost:8080/xxx/サーブレット名?param1=value1&param2=value2&・・・
    <a href="/xxx/サーブレット名?param1=value1&param2=value2&・・・">yyy</a>
    URLの後に"?"に続けて、「パラメータ名=パラメータ値」と記述します。
    複数パラメータを設定する場合は、"&"で連結していきます。
  • POSTメソッド
    <form>タグで「method="post"」と指定した場合に使用される送信方法です。
    <input>タグのnameにパラメータ名、valueにパラメータの初期値を設定します。
    これはテキストボックスやテキストエリアなどのユーザの入力値をサーバへ渡す場合によく使用されます。
    (例)
    <form action="/xxx/サーブレット名" method="post">
    <input type="text" name="param1" value="textの初期値"> --- テキストボックス
    <textarea name="param2">textareaの初期値</textarea> --- テキストエリア
    <input type="hidden" name="param3" value="hiddenの値"> --- ブラウザからは見えない
    </form>
  • doGet()とdoPost()
    GETメソッドでサーブレットが呼ばれた場合、doGet()というメソッドが呼び出されます。
    一方、POSTメソッドでサーブレットが呼ばれた場合、doPost()というメソッドが呼び出されます。
    この仕組みを使えば、同じサーブレットでもGETメソッドで呼び出した場合とPOSTメソッドで呼び出した場合で異なる処理を行わせることができます。
    サンプルソース:GetPostServlet?.java
    package sample.servlet;
    
    //==========================================================
    //import
    
    //J2SE
    import java.io.*;
    
    //J2EE
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * GetとPostで処理内容を変更するサーブレット。<br>
     */
    public class GetPostServlet extends HttpServlet {
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * GETメソッドでサーブレットが呼ばれた場合に、このメソッドが呼び出されます。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // ContentTypeの設定
            res.setContentType("text/html; charset=Windows-31J");
    
            // レスポンスからPrintWriterを取得
            PrintWriter out = res.getWriter();
    
            // HTMLの出力
            out.println("<html>");
            out.println("<head>");
            out.println("<title>GetPostServlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>GETメソッドでサーブレットが呼び出されました</h1>");
            out.println("</body>");
            out.println("</html>");
        }
    
        /**
         * POSTメソッドでサーブレットが呼ばれた場合に、このメソッドが呼び出されます。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        protected void doPost(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // ContentTypeの設定
            res.setContentType("text/html; charset=Windows-31J");
    
            // レスポンスからPrintWriterを取得
            PrintWriter out = res.getWriter();
    
            // HTMLの出力
            out.println("<html>");
            out.println("<head>");
            out.println("<title>GetPostServlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>POSTメソッドでサーブレットが呼び出されました</h1>");
            out.println("</body>");
            out.println("</html>");
        }
    
    }
    このサーブレットは、GETメソッドで呼び出された場合は「GETメソッドでサーブレットが呼び出されました」、
    POSTメソッドで呼び出された場合は「POSTメソッドでサーブレットが呼び出されました」と表示します。

    ちなみに、最初に説明したservice()メソッドは、GETメソッドの場合もPOSTメソッドの場合も両方呼び出されます。
    そこで、GETメソッドとPOSTメソッドで処理を分ける必要がない場合は、service()メソッドをオーバーライドすればどちらにも対応できます。
    (実際は、service()メソッドのデフォルトの動作でリクエストのヘッダ情報に基づいてdoGet()やdoPost()を呼び分けているだけなので、この処理自体を上書きしてしまうというわけです。)
     
  • 課題
    上のサーブレットを、GETメソッドとPOSTメソッドの両方で呼び出すHTMLを作成し、実際に呼び出してみて下さい。
     

リクエストパラメータの取得

  • getParameter() リクエストパラメータは、リクエストクラス(javax.servlet.http.HttpServletRequest?)の getParameter(String name) メソッドで取得することができます。
    このとき、nameにはパラメータ名を指定します。
    対応するパラメータが存在しない場合はnullが返されます。
    サンプルソース:GetParameterServlet?.java
    package sample.servlet;
    
    //==========================================================
    //import
    
    //J2SE
    import java.io.*;
    
    //J2EE
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * リクエストパラメータを取得して、そのまま表示するサーブレット。<br>
     */
    public class GetParameterServlet extends HttpServlet {
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * service()メソッドです。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // ContentTypeの設定
            res.setContentType("text/html; charset=Windows-31J");
    
            // レスポンスからPrintWriterを取得
            PrintWriter out = res.getWriter();
    
            // //////////////////////////////////////////////////////////
            // HTMLの出力
            out.println("<html>");
            out.println("<head>");
            out.println("<title>リクエストパラメータの取得</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<center><h1>リクエストパラメータの取得</h1></center>");
            out.println("<hr>");
    
            // ==========================================================
            // リクエストパラメータの取得
            String param = req.getParameter("param");
    
            // 取得したパラメータの値をそのまま出力
            out.println("param=" + param);
            // ==========================================================
    
            out.println("</body>");
            out.println("</html>");
        }
    
    }
    上記で作成したサーブレットを呼び出すためのHTMLコード
    filecallGetParameterServlet.html
  • getParameterValues?()
    チェックボックスなどで同じ名前のパラメータが複数送られた場合、getParameter() メソッドでは最初の値しか取得できないので問題が生じます。
    そういう場合は、getParameterValues?(String name) メソッドを使用すれば、全ての値を配列で取得することができます。
    パラメータに値が1つしかない場合は、配列の大きさは1です。
    getParameter() メソッドと同じく、nameにはパラメータ名を指定し、対応するパラメータが存在しない場合はnullが返されます。
    サンプルソース:GetParameterValuesServlet?.java
    package sample.servlet;
    
    //==========================================================
    //import
    
    //J2SE
    import java.io.*;
    
    //J2EE
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * リクエストパラメータを配列で取得して、全て表示するサーブレット。<br>
     */
    public class GetParameterValuesServlet extends HttpServlet {
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * service()メソッドです。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // ContentTypeの設定
            res.setContentType("text/html; charset=Windows-31J");
    
            // レスポンスからPrintWriterを取得
            PrintWriter out = res.getWriter();
    
            // //////////////////////////////////////////////////////////
            // HTMLの出力
            out.println("<html>");
            out.println("<head>");
            out.println("<title>リクエストパラメータを配列で取得</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<center><h1>リクエストパラメータを配列で取得</h1></center>");
            out.println("<hr>");
    
            // ==========================================================
            // リクエストパラメータを配列で取得
            String[] param = req.getParameterValues("param");
    
            // パラメータ名を出力
            out.print("param=");
    
            // 対応するパラメータが存在しなかった場合
            if (param == null) {
                // nullと出力
                out.println("null");
            }
            // 対応するパラメータが存在した場合
            else {
                // 配列の要素数に応じてループをまわす
                for (int i = 0; i < param.length; i++) {
                    // 最初以外の場合
                    if (i != 0) {
                        // 前の要素との間の区切り文字を出力
                        out.print(", ");
                    }
    
                    // 現在の要素の値を出力
                    out.print(param[i]);
                }
    
                // 改行
                out.println();
            }
            // ==========================================================
    
            out.println("</body>");
            out.println("</html>");
        }
    
    }
    上記で作成したサーブレットを呼び出すためのHTMLコード
    filecallGetParameterValuesServlet.html
  • getParameterNames?()
    パラメータ名がわからない場合は、getParameterNames?() メソッドで全てのパラメータ名を取得することができます。
    ただし、この戻り値は文字列の配列ではなく java.util.Enumeration なので注意が必要です。
    サンプルソース:GetParameterNamesServlet?.java
    package sample.servlet;
    
    //==========================================================
    //import
    
    //J2SE
    import java.io.*;
    import java.util.*;
    
    //J2EE
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * 全てのリクエストパラメータを取得して、そのまま表示するサーブレット。<br>
     */
    public class GetParameterNamesServlet extends HttpServlet {
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * service()メソッドです。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // ContentTypeの設定
            res.setContentType("text/html; charset=Windows-31J");
    
            // レスポンスからPrintWriterを取得
            PrintWriter out = res.getWriter();
    
            // //////////////////////////////////////////////////////////
            // HTMLの出力
            out.println("<html>");
            out.println("<head>");
            out.println("<title>全てのリクエストパラメータを取得</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<center><h1>全てのリクエストパラメータを取得</h1></center>");
            out.println("<hr>");
    
            // ==========================================================
            // 全てのパラメータ名を取得し、ループをまわす
            for (Enumeration<String> e = req.getParameterNames(); e
                    .hasMoreElements();) {
                // 現在の要素の値(パラメータ名)を取得してStringにキャスト
                String paramName = e.nextElement();
    
                // パラメータ名に対応する値を取得
                String paramValue = req.getParameter(paramName);
    
                // 「パラメータ名=値」 + 改行の<br>を出力
                out.println(paramName + "=" + paramValue + "<br>");
            }
    
            // ==========================================================
    
            out.println("</body>");
            out.println("</html>");
        }
    
    }
    上記で作成したサーブレットを呼び出すためのHTMLコード
    filecallGetParameterNamesServlet.html
  • 重要
    • 上のサンプルプログラムでは、パラメータの値に全角文字が含まれていると"?"に文字化けしてしまいます。 この問題の解決方法は、次の全角文字を含むパラメータの取得で解説します。
       
    • 上のサンプルプロプラムのように取得したパラメータの値をそのまま出力するのは、実は重大なセキュリティホールにつながるので危険です。 詳しくは、特殊文字のエスケープで解説します。
 
  • 課題
    2つの整数をリクエストパラメータとして受け取り、足し算を行うサーブレット「CalcServlet?」を作成して下さい~。 (整数以外が入力された場合はエラーが発生しても構いませんが、余力がある場合は「整数を入力して下さい」というメッセージが表示されるようにしてみて下さい。)
    filecallCalcServlet.html
     

全角文字を含むパラメータの取得

Tomcatで全角文字を含むパラメータを、getParameter()メソッドで普通に取得すると、"?"に文字化けしてしまいます。
そこで、以下のような特殊な変換処理を行う必要があります。
サンプルソース:GetJapaneseParameterServlet?.java

package sample.servlet;

//==========================================================
//import

//J2SE
import java.io.*;

//J2EE
import javax.servlet.*;
import javax.servlet.http.*;

/**
 * リクエストパラメータを取得して、そのまま表示するサーブレット(全角文字に対応)。<br>
 */
public class GetJapaneseParameterServlet extends HttpServlet {
    // ==========================================================
    // メソッド

    // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
    // オーバーライドするメソッド

    /**
     * service()メソッドです。<br>
     * 
     * @param req
     *            リクエスト
     * @param res
     *            レスポンス
     * @exception ServletException
     *                サーブレット例外
     * @exception IOException
     *                入出力例外
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        // ContentTypeの設定
        res.setContentType("text/html; charset=Windows-31J");

        // レスポンスからPrintWriterを取得
        PrintWriter out = res.getWriter();

        // //////////////////////////////////////////////////////////
        // HTMLの出力
        out.println("<html>");
        out.println("<head>");
        out.println("<title>全角文字を含むパラメータの取得</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<center><h1>全角文字を含むパラメータの取得</h1></center>");
        out.println("<hr>");

        // ==========================================================
        // リクエストパラメータの取得
        String param = req.getParameter("param");

        // //////////////////////////////////////////////////////////
        // 全角文字を扱えるように取得したパラメータを変換

        // 誤った文字コード「8859_1」で取得された文字列(Unicode)をバイト配列に戻す
        byte[] bytes = param.getBytes("8859_1");

        // バイト配列を今度はクライアントの文字コード(今回は「Windows-31J」)で文字列に組み立てなおす
        String japaneseParam = new String(bytes, "Windows-31J");

        // (注)普通はこのように一行にパラメータの取得と変換処理をまとめて書きます
        // String japaneseParam = new
        // String(req.getParameter("param").getBytes("8859_1"), "Windows-31J");

        // //////////////////////////////////////////////////////////

        // 取得したパラメータの値をそのまま出力
        out.println("param=" + japaneseParam);
        // ==========================================================

        out.println("</body>");
        out.println("</html>");
    }

}

上記で作成したサーブレットを呼び出すためのHTMLコード
filecallGetJapaneseParameterServlet.html
このソースで行っている処理を完全に理解する必要はありません。
今は「お約束」として覚えておくだけで結構です。
なお、new String(bytes, "Windows-31J")の部分は、 java.io.UnsupportedEncodingException? という例外を投げるので注意が必要です。
また、getParameter() でパラメータが存在せずにnullが返された場合、変換処理を行う際に java.lang.NullPointerException? が発生します。

重要
全角文字を含むパラメーターが文字化けするかどうかは、アプリケーションサーバによって異なります。
アプリケーションサーバの中には、全角文字を含むパラメータに対応する処理を自動的に行ってくれるものもあります。
そのようなアプリケーションサーバでこの変換処理を行うと、二重に処理が行われてしまい、かえって文字化けしてしまうので注意が必要です。
また、パラメータの取得の度にこの変換処理を行っていたら、クライアントの文字コードが変わったときの修正が大変です。

そこで、通常はサーブレットで getParameter()を使用する度に変換処理を直接実装するのではなく、パラメータの変換処理を専門に行うクラスを作成し、その中で必要に応じて変換処理を行います。
そうすると、環境依存の少ない、汎用性の高いプログラムを作成することができます。
  • 課題
    上の説明にある、全角文字を含むパラメータの変換処理を専門に行うクラス「ParameterConverter?」を作成してみましょう。
    このクラスは、コンストラクタでリクエストクラスのインスタンスを受け取り、getParameter(String name) メソッドで全角パラメータを変換してから返します。
    変換を行うかどうかのフラグと、クライアントの文字コードは定数にしておくとよいでしょう。
    (余力があれば、getParameterValues?(String name) メソッドも作成してみましょう。)
    ParameterConverter.png

特殊文字のエスケープ

  • 特殊文字をエスケープする必要性
    パラメータの値をそのまま表示するような処理を行っている場合、タグなどの特殊文字が入力された場合に問題が生じます。
    例えば、パラメータの値が「<input>」という文字列の場合、そのまま表示するとinputタグの入力フィールドが表示されてしまいます。
    さらには、パラメータにJavaScript?などが渡された場合、訪問者のブラウザから不正にCookie情報を取得したり、架空のフォームを表示させて訪問者から個人情報等を収集される可能性もあります。
    この問題は「クロスサイトスクリプティング問題」と呼ばれ、重大なセキュリティホールとなります。
    この問題を回避するためには、次のように特殊文字を「&xxx;」という形式の代替文字にエスケープする必要があります。(最後の「;」は忘れやすいので注意)
     特殊文字  代替文字 
    &amp;
    &lt;
    &gt;
    &quot;
    (半角スペース)&nbsp;
(補足)
半角スペースは変換しなくてもセキュリティ上の問題はありません。
しかし、変換しないとHTMLの仕様上、複数のスペースが連続していても1つにまとめられてしまうので、入力データと出力結果が違って見えてしまいます。
  • 課題
    上記の特殊文字をエスケープする専用のメソッドを作成し、パラメータを出力する場合は必ずそのメソッドを通すようにします。
    さらに、そのメソッドを特殊文字のエスケープを行う専用のクラスに定義しておくと、どのサーブレットやJSPからも使用することができるので、より汎用性の高いプログラムを作成することができます。
    EscapeUtil.png
    解答サンプル:fileEscapeUtil.java

他の画面の呼び出し

  • リダイレクト
    レスポンスクラス(javax.servlet.http.HttpServletResponse?)の sendRedirect(String location) メソッドで、指定したURLにリダイレクトすることができます。
    この方法では外部のサイトのURLも指定することができます。
    しかし、この方法では遷移先のページにパラメータを引き渡すことはできないので、同じWebアプリケーションの別のURLに遷移させたい場合は、通常は下のフォワードを使用します。
    サンプルソース:SendRedirectServlet?.java
    package sample.servlet;
    
    //==========================================================
    //import
    
    //J2SE
    import java.io.*;
    
    //J2EE
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * 他のURLにリダイレクトするサーブレット。<br>
     */
    public class SendRedirectServlet extends HttpServlet {
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * service()メソッドです。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // 指定したURLにリダイレクトする
            // (このように外部のサイトのURLを指定することもできます)
            res.sendRedirect("http://www.google.com");
    
            // 自分自身のサイトのURLにリダイレクトする場合は、このようにサーバのルートパスから指定します
            // res.sendRedirect("/kensyu/servlet/HelloWorldServlet");
        }
    
    }
  • フォワード
    RequestDispatcher?(javax.servlet.RequestDispatcher?)の forward(ServletRequest? request, ServletResponse? response) メソッドで、サーバ上のリソース(サーブレット, JSPファイル, HTMLファイル)にリクエストをフォワードすることができます。
    このRequestDispatcher?というクラスのインスタンスは、リクエストクラス (javax.servlet.http.HttpServletResponse?)またはサーブレットコンテキストクラス (javax.servlet.ServletContext?)の getRequestDispatcher?(String path) メソッドで取得することができます。
    この方法では遷移先のページにパラメータを引き渡すことができます。
    path に指定するURLには、Webアプリケーション名は含めないので注意して下さい。
    また、自分自身のWebアプリケーション内のリソースにしかアクセスできないので、外部のサイトのURLや、同じサーバの別のWebアプリケーションのURLを指定することはできません。
    サンプルソース:ForwardServlet?.java
    package sample.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * サーバ上のリソース(サーブレット, JSPファイル, HTMLファイル)にリクエストをフォワードするサーブレット。<br>
     */
    public class ForwardServlet extends HttpServlet {
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * service()メソッドです。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // リソース(サーブレット, JSPファイル, HTMLファイル)のパスを指定して、リクエストからRequestDispatcherを取得
            // (「/kensyu」というようにWebアプリケーション名からではなく、Webアプリケーション内のディレクトリから指定するので注意して下さい。)
            RequestDispatcher rd = req
                    .getRequestDispatcher("/servlet/GetParameterServlet");
    
            // フォワード
            rd.forward(req, res);
        }
    
    }
  • インクルード
    RequestDispatcher?(javax.servlet.RequestDispatcher?)の include(ServletRequest? request, ServletResponse? response) メソッドで、サーバ上のリソース(サーブレット, JSPファイル, HTMLファイル)の内容をレスポンスにインクルードすることができます。
    インクルードというのは、簡単に言えば部品として取り込むということです。
    このRequestDispatcher?というクラスのインスタンスは、フォワードの場合と同じく、リクエストクラス (javax.servlet.http.HttpServletResponse?)またはサーブレットコンテキストクラス (javax.servlet.ServletContext?)の getRequestDispatcher?(String path) メソッドで取得することができます。
    path に指定するURLには、Webアプリケーション名は含めないので注意して下さい。
    また、自分自身のWebアプリケーション内のリソースにしかアクセスできないので、外部のサイトのURLや、同じサーバの別のWebアプリケーションのURLを指定することはできません。
    サンプルソース:IncludeServlet?.java
    package sample.servlet;
    
    //==========================================================
    //import
    
    //J2SE
    import java.io.*;
    
    //J2EE
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * サーバ上のリソース(サーブレット, JSPファイル, HTMLファイル)をインクルードするサーブレット。<br>
     */
    public class IncludeServlet extends HttpServlet {
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * service()メソッドです。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // ContentTypeの設定
            res.setContentType("text/html; charset=Windows-31J");
    
            // レスポンスからPrintWriterを取得
            PrintWriter out = res.getWriter();
    
            // //////////////////////////////////////////////////////////
            // HTMLの出力
            out.println("<html>");
            out.println("<head>");
            out.println("<title>インクルード</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<center><h1>インクルード</h1></center>");
            out.println("<hr>");
            out.println("インクルード開始>>><br>");
    
            // ==========================================================
            // リソース(サーブレット, JSPファイル, HTMLファイル)のパスを指定して、リクエストからRequestDispatcherを取得
            // (「/kensyu」というようにWebアプリケーション名からではなく、Webアプリケーション内のディレクトリから指定するので注意して下さい。)
    
            RequestDispatcher rd = req.getRequestDispatcher("/html/hogehoge.html");
    
            // インクルード
            rd.include(req, res);
            // ==========================================================
    
            out.println("<<<インクルード終了<br>");
            out.println("</body>");
            out.println("</html>");
        }
    
    }
    この結果として、このような画面が生成されます。
    fileincludeResult.html
     

画面間の情報の共有

  • リクエスト・セッション・アプリケーション属性
    サーブレットでは、画面間で情報を共有するために、リクエスト・セッション・アプリケーション属性という3つの方法が用意されています。 (これらは、変数を入れておく箱のようなものだと思って下さい。)
    種類管理しているクラス管理しているクラスの取得方法管理しているクラスの取得方法対象主な用途
    リクエストjavax.servlet.http.HttpServletRequest?(リクエストクラス)service(), doGet(), doPost()メソッドの引数として与えられる現在のリクエストが終了するまでリクエストごとJSPへの情報の引渡し
    セッションjavax.servlet.http.HttpSession?(セッションクラス)リクエストクラスの getSession() メソッド最初にセッションオブジェクトが作成されてから消去されるまで(タイムアウト有り)ユーザごと画面間の情報の引渡し
    アプリケーションjavax.servlet.ServletContext?(サーブレットコンテキストクラス)サーブレットの getServletContext?() メソッドアプリケーションの開始から終了までずっとアプリケーション全体アプリケーション全体で共有する情報(あまり使用されない)
    <注>
    アプリケーションサーバを再起動すると、基本的に全ての属性が削除されます。(ときどき削除されないこともあります)
     
    属性を登録・取得・削除するには、管理しているクラスの以下のメソッドを使用します。
    イメージとしては、リクエストパラメータと同じように、名前とオブジェクトを関連付けて登録しておいて、後で名前をキーにしてオブジェクトを取り出すといった感じです。
    なお、属性の値には int などの基本データ型は使用することはできません。
    メソッド機能
    void setAttribute(String name, Object object)属性名にオブジェクトを結びつけて登録します。指定した名前がすでに使用されている場合は、上書きされます。
    Object getAttribute(String name)指定した名前に対応する属性を返します。指定された名前に一致する属性が無い場合は nullを返します。
    java.util.Enumeration getAttributeNames?()全ての属性名を返します。
    void removeAttribute(String name)指定した名前に対応する属性を削除します。
     
    サンプルソース:UseAttributeServlet?.java
    package sample.servlet;
    
    //==========================================================
    //import
    
    //J2SE
    import java.io.*;
    
    //J2EE
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * リクエスト・セッション・アプリケーション属性を使用するサーブレット。<br>
     */
    public class UseAttributeServlet extends HttpServlet {
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * service()メソッドです。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // ==========================================================
            // リクエスト・セッション・アプリケーション属性を設定
    
            // セッションを取得
            HttpSession session = req.getSession();
    
            // サーブレットコンテキストを取得
            ServletContext sc = getServletContext();
    
            // リクエスト属性を設定
            req.setAttribute("RequestAttribute", new Integer(1));
    
            // セッション属性を設定
            session.setAttribute("SessionAttribute", new Integer(2));
    
            // アプリケーション属性を設定
            sc.setAttribute("ApplicationAttribute", new Integer(3));
            // ==========================================================
    
            // ContentTypeの設定
            res.setContentType("text/html; charset=Windows-31J");
    
            // レスポンスからPrintWriterを取得
            PrintWriter out = res.getWriter();
    
            // //////////////////////////////////////////////////////////
            // HTMLの出力
            out.println("<html>");
            out.println("<head>");
            out.println("<title>リクエスト・セッション・アプリケーション属性の使用</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<center><h1>リクエスト・セッション・アプリケーション属性の使用</h1></center>");
            out.println("<hr>");
    
            // ==========================================================
            // リクエスト・セッション・アプリケーション属性の取得
    
            // リクエスト属性を取得して元の型にキャスト
            Integer requestAttribute = (Integer) req
                    .getAttribute("RequestAttribute");
    
            // セッション属性を取得して元の型にキャスト
            Integer sessionAttribute = (Integer) session
                    .getAttribute("SessionAttribute");
    
            // アプリケーション属性を取得して元の型にキャスト
            Integer applicationAttribute = (Integer) sc
                    .getAttribute("ApplicationAttribute");
    
            // 取得した属性の値をそのまま出力
            out.println("リクエスト属性=" + requestAttribute);
            out.println("セッション属性=" + sessionAttribute);
            out.println("アプリケーション属性=" + applicationAttribute);
    
            // ==========================================================
    
            out.println("</body>");
            out.println("</html>");
        }
    
    }
  • セッション属性を使用する際の注意
    • セッションをむやみに使いすぎない
      セッションはユーザごとに作成されるので、あまり大きなオブジェクトをセッション属性に登録するのは危険です。
      たとえ1ユーザあたりのメモリ使用量は大したことはなくても、10,000人~100,000人規模のユーザが使用した場合には大量のメモリを使用することになり、メモリエラーを引き起こす可能性があります。
    • 不要になった属性は直ちに削除する
      セッションに登録されているオブジェクトは、ガベージコレクションの対象になりません。
      そのため、不要になった属性をいつまでも削除せずに放置しておくと、メモリが足りなくなる恐れがあります。
    • セッションがタイムアウトになった場合を想定したプログラムを組む
      セッションがタイムアウトになると、getAttribute() メソッドで属性を取得しようとしたときにnullが返されます。
      そのため、これを考慮したプログラムを組んでおかないと、取得した値を使用しようとしたときに java.lang.NullPointerException? が発生してしまいます。
      なお、セッションのタイムアウト時間は設定ファイルで変更できます。(Tomcatの場合、デフォルトでは30分)
  • 課題
    セッション属性を使用して、呼び出される度にカウントを増やしていき、そのカウントを画面に表示するサーブレット「SessionCountServlet?」を作成して下さい。
    画面イメージfilecount.html

サーブレットの初期化・終了処理

  • web.xml
    今までは、Webアプリケーションのデフォルトの設定でサーブレットを動かしてきましたが、通常のシステムではある程度カスタマイズするのが一般的です。
    Tomcatでは、「web.xml」というXMLファイルでWebアプリケーションの定義を行います。
    (このファイルは、「WEB-INF」ディレクトリの直下に配置します。)
     
    このファイルでは、サーブレットの初期化パラメータや初期化のタイミング、サーブレットのURLマッピング、ウェルカムページなどを設定することができます。
  • init()
    サーブレットでは、init(ServletConfig? config) メソッドをオーバーライドすることにより、初期化処理を行うことができます。
    この初期化処理は、サーブレットが最初に呼び出されたときに1回だけ呼び出されます。
    ただし、定義ファイルの設定によっては、アプリケーションサーバの起動時に初期化処理を行わせることも可能です。
    なお、定義ファイルから初期化パラメータを渡すこともできます。
    初期化パラメータを取得するには、サーブレットコンフィグクラス(javax.servlet.ServletConfig?)の getInitParameter?(String name) メソッドを使用します。
  • destroy()
    サーブレットでは、destroy() メソッドをオーバーライドすることにより、終了処理を行うことができます。
    この終了処理は、サーブレットが廃棄されるとき(アプリケーションサーバが停止するとき)に1回だけ呼び出されます。

サンプルソース:InitDestroyServlet?.java

package sample.servlet;

//==========================================================
//import

//J2SE
import javax.servlet.*;
import javax.servlet.http.*;

/**
 * 初期化・終了処理を実装したサーブレット。<br>
 */
public class InitDestroyServlet extends HttpServlet {
    // ==========================================================
    // メソッド

    // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
    // オーバーライドするメソッド

    /**
     * サーブレットの初期化処理を行います。<br>
     * 
     * @param config
     *            サーブレットコンテキスト
     * @exception ServletException
     *                サーブレット例外
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        // 初期化パラメータを取得
        String initParam1 = config.getInitParameter("InitParam1");
        String initParam2 = config.getInitParameter("InitParam2");

        // メッセージを出力
        // (本当は、このようにサーブレットの中で標準出力にメッセージを出力するのは良くありません)
        System.out.println("*** InitDestroyServlet の初期化処理 ***");
        System.out.println("InitParam1=" + initParam1);
        System.out.println("InitParam2=" + initParam2);
    }

    /**
     * サーブレットの終了処理を行います。<br>
     */
    public void destroy() {
        // メッセージを出力
        // (本当は、このようにサーブレットの中で標準出力にメッセージを出力するのは良くありません)
        System.out.println("*** InitDestroyServlet の終了処理 ***");
    }

}

Cookieの読み書き

  • サーブレットでCookieは必要か?
    サーブレットでは、セッションを使うことにより画面間の情報の共有を行うことができるので、Cookieを使用する必要性はあまりありません。
    また、セッションでは任意のオブジェクトを扱えるのに比べて、Cookieでは文字列しか扱うことができません。
    それに、Cookieはクライアントのブラウザが受け入れないかぎり使用することができません。
    これらの理由から、サーブレットでCookieを使用することはまれです。
    しかし、既存のシステムと連携する場合や、複数の会社やプロジェクトチームによって開発が行われる場合などは、セッションが使用できないのでCookieを使用することがあります。
  • Cookieクラス
    サーブレットでCookieを扱うにはCookieクラス(javax.servlet.http.Cookie)を使用します。
    このクラスには、Cookieの名前・値といった基本情報のほかに、コメントやパス・ドメイン・最長存続期間・バージョンといったオプション情報のsetter, getter が用意されています。
  • Cookieの取得
    既存のCookieの取得は、リクエストクラス(javax.servlet.http.HttpServletRequest?)の getCookies() メソッドで行います。
    ただし、このメソッドでは全てのCookieを配列で取得することしかできないので、目的のCookieを取得するには、下のサンプルソースのように自分でループをまわして名前の一致するCookieを検索する必要があります。
  • Cookieの設定
    Cookieを設定するには、まずCookieクラスのインスタンスを生成する際に、コンストラクタで名前と値を決定します。
    そして、レスポンスクラス(javax.servlet.http.HttpServletResponse?)クラスの addCookie(Cookie cookie) メソッドに生成したCookieのインスタンスを渡すことにより、実際にレスポンスにCookieを追加します。
    サンプルソース:CookieUseServlet?.java
    package sample.servlet;
    
    //==========================================================
    //import
    
    //J2SE
    import java.io.*;
    
    //J2EE
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * Cookieを使用するサーブレット。<br>
     */
    public class CookieUseServlet extends HttpServlet {
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * service()メソッドです。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
    
            // ContentTypeの設定
            res.setContentType("text/html; charset=Windows-31J");
    
            // レスポンスからPrintWriterを取得
            PrintWriter out = res.getWriter();
    
            // //////////////////////////////////////////////////////////
            // HTMLの出力
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Cookieの使用</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<center><h1>Cookieの使用</h1></center>");
            out.println("<hr>");
    
            // ==========================================================
            // Cookieを取得・設定
    
            // 全てのCookieを取得
            Cookie[] cookies = req.getCookies();
    
            // テスト用のCookie
            Cookie testCookie = null;
    
            // Cookieの配列が取得できた場合
            if (cookies != null) {
                // Cookieの配列の要素数に応じてループをまわす
                for (int i = 0; i < cookies.length; i++) {
                    // Cookieの名前が「testCookie」の場合
                    if (cookies[i].getName().equals("testCookie")) {
                        // 現在のCookieを変数に設定
                        testCookie = cookies[i];
    
                        // これ以上検索を続けても意味がないので、ループを抜ける
                        break;
                    }
                }
            }
    
            // Cookieが見つからなかった場合(初めての場合)
            if (testCookie == null) {
                // メッセージを出力
                out.println("Cookie「testCookie」が見つかりませんでした");
    
                // Cookieクラスのインスタンスを生成
                Cookie cookie = new Cookie("testCookie", "CookieValue");
    
                // 作成したCookieをレスポンスに追加
                res.addCookie(cookie);
            }
            // Cookieが見つかった場合
            else {
                // Cookieの値を出力
                out.println("testCookie=" + testCookie.getValue());
            }
    
            // ==========================================================
    
            out.println("</body>");
            out.println("</html>");
        }
    
    }

バイナリデータの出力

  • サーブレットでバイナリデータを出力する必要性
    サーブレットでは、通常のHTML以外にバイナリデータを出力することもできます。
    例えば、サーバー上の任意のファイルをダウンロードしたり、画像データをファイルやデータベースから読み込んでそのままブラウザに出力することもできます。
    この機能を使えば、ファイルがダウンロードされた回数をカウントしたり、ランダムに画像を切り替えたりすることもできます。
  • 画像表示用サーブレット
    以下に、画像用のサーブレット「ImageServlet?」のソースを示します。
    このサーブレットは、画像ファイルを読み込んでその内容をバイナリデータとしてそのまま出力しています。
    サンプルソース:ImageServlet?.java
    package sample.servlet;
    
    //==========================================================
    //import
    
    //J2SE
    import java.io.*;
    
    //J2EE
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * 画像ファイルを読み込んで、バイナリデータとして出力するサーブレット。<br>
     */
    public class ImageServlet extends HttpServlet {
        // ==========================================================
        // 定数
    
        /**
         * 読み込む画像ファイル
         */
        public static final String IMAGE_FILE = "/temp/hoge.png";
    
        // ==========================================================
        // メソッド
    
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // オーバーライドするメソッド
    
        /**
         * service()メソッドです。<br>
         * 
         * @param req
         *            リクエスト
         * @param res
         *            レスポンス
         * @exception ServletException
         *                サーブレット例外
         * @exception IOException
         *                入出力例外
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            // 入力ストリームに画像ファイルを設定
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(
                    IMAGE_FILE));
    
            // 出力ストリームにレスポンスから取得した出力ストリームを設定
            BufferedOutputStream out = new BufferedOutputStream(res
                    .getOutputStream());
    
            // バイト数
            int c = -1;
    
            // 入力ストリームを読み終えるまで
            while ((c = in.read()) != -1) {
                // 出力ストリームにバッファリングする
                out.write(c);
            }
    
            // バッファリングされた出力ストリームをフラッシュ
            out.flush();
    
            // 出力ストリームを閉じる
            out.close();
    
            // 入力ストリームを閉じる
            in.close();
        }
    
    }
    このサーブレットを呼び出すHTML「filecallImageServlet.html」の内容は以下の通りです。
    <img>タグのsrc属性に、画像ファイルを指定する代わりにサーブレットを指定しています。
    <html>
        <head>
            <meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">
            <title>画像表示サーブレットの呼び出し</title>
        </head>
        <body>
            <center>
                <h1>画像表示サーブレットの呼び出し</h1>
                <hr>
                <h2>これはサーブレットから出力された画像です</h2>
                
                <img src="/kensyu/servlet/ImageServlet">
            </center>
        </body>
    </html>

総合課題

  • 下の図のような、ログイン・ログアウトを伴うアプリケーションを作成して下さい。
    ログイン画面はHTMLで、その他の2画面はサーブレットで作成して下さい。
    total.png

  • コーディング条件
    • 入力された名前の保持にはセッション属性を使うこと
    • 名前に全角文字が入力されても正常に表示すること
    • 名前を表示する際は特殊文字のエスケープを行うこと
    • ログアウト画面を表示した後にはセッションを削除すること
    • ログアウト画面でセッションの取得に失敗した場合は、ログアウト画面を表示せずにログイン画面にリダイレクトすること

  • 参考のHTML
    ログイン画面:filelogin.html → ログイン後の画面:filehello.html → ログアウト画面 filelogout.html

  • 解答サンプル
    fileexercise_20090124.zip
    Eclipseのプロジェクトごとアーカイブにしてあります。
    確認するときはhttp://www.javadrive.jp/eclipse3/project/index4.htmlなどを参考にプロジェクトのインポートを行ってください。
     
    本当はこういったかたちで(fileexercise_20090124_2.zip)ServletとJSPを組み合わせて作成するのが望ましいです。
    JSPの作成の内容も合わせて確認してください。

Java勉強会カリキュラムに戻る


添付ファイル: fileSessionCountServlet.java 417件 [詳細] fileexercise_20090124_2.zip 330件 [詳細] fileexercise_20090124.zip 353件 [詳細] fileEscapeUtil.java 483件 [詳細] filelogout.html 388件 [詳細] filehello.html 386件 [詳細] filelogin.html 397件 [詳細] filetotal.png 325件 [詳細] filecount.html 391件 [詳細] fileincludeResult.html 377件 [詳細] fileEscapeUtil.png 273件 [詳細] fileParameterConverter.png 313件 [詳細] filecallCalcServlet.html 392件 [詳細] filecalc.html 205件 [詳細] filecallGetJapaneseParameterServlet2.html 165件 [詳細] filecallGetJapaneseParameterServlet.html 352件 [詳細] filecallImageServlet.html 387件 [詳細] filecallGetParameterValuesServlet.html 392件 [詳細] filecallGetParameterServlet.html 424件 [詳細] filecallGetParameterNamesServlet.html 389件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-01-24 (土) 21:55:08 (591d)