Servlet セッショントラッキング

HTTP は「ステートレス」プロトコルです。つまり、クライアントがWebページを取得するたびに、クライアントはWebサーバーに対して個別の接続を開き、サーバーは以前のクライアントリクエストの記録を自動的に保持しません。

しかし、WebクライアントとWebサーバー間のセッションを維持するには、次の3つの方法があります。

Cookies

Webサーバーは、各WebクライアントのCookieとして一意のセッションIDを割り当てることができます。クライアントの後続のリクエストでは、受け取ったCookieを使用して識別できます。

これは効果的な方法ではないかもしれません。多くのブラウザがCookieをサポートしていないため、この方法でセッションを維持することはお勧めしません。

隠しフォームフィールド

Webサーバーは、一意のセッションIDとともに、隠しHTMLフォームフィールドを送信できます。次のようになります。

<input type="hidden" name="sessionid" value="12345">

このエントリは、フォームが送信されると、指定された名前と値がGETまたはPOSTデータに自動的に含まれることを意味します。Webブラウザがリクエストを送信するたびに、session_id値を使用してさまざまなWebブラウザを追跡し続けることができます。

これはセッション追跡を維持する効果的な方法かもしれませんが、通常のハイパーテキストリンク(<A HREF...>)をクリックしてもフォーム送信は発生しないため、隠しフォームフィールドは通常のセッション追跡もサポートしません。

URL リライティング

各URLの末尾に追加のデータを追加してセッションを識別できます。サーバーはそのセッション識別子を、保存されているセッションに関連するデータと関連付けます。

たとえば、http://w3cschool.cc/file.htm;sessionid=12345 のように、セッション識別子が sessionid=12345 として追加されます。この識別子はWebサーバーがクライアントを識別するためにアクセスできます。

URLリライティングはセッションを維持するより良い方法であり、ブラウザがCookieをサポートしていない場合でもうまく機能します。ただし、欠点は、非常に単純な静的HTMLページであっても、ページにセッションIDを割り当てるために各URLを動的に生成することです。

HttpSession オブジェクト

上記の3つの方法に加えて、ServletはHttpSessionインターフェースも提供します。このインターフェースは、複数のページリクエストやWebサイトへのアクセスにわたってユーザーを識別し、ユーザーに関する情報を保存する方法を提供します。

Servletコンテナはこのインターフェースを使用して、HTTPクライアントとHTTPサーバー間のセッションを作成します。セッションは、複数の接続またはページリクエストにわたって、指定された期間続きます。

HttpServletRequest のパブリックメソッドを呼び出すことで、getSession()HttpSession オブジェクトを取得します。次のようになります。

HttpSession session = request.getSession();

クライアントにドキュメントコンテンツを送信する前に呼び出す必要があります。request.getSession()。以下に、HttpSession オブジェクトで利用可能ないくつかの重要なメソッドをまとめます。

番号メソッド & 説明
1public Object getAttribute(String name)
このメソッドは、セッション内で指定された名前を持つオブジェクトを返します。指定された名前のオブジェクトがない場合は null を返します。
2public Enumeration getAttributeNames()
このメソッドは、セッションにバインドされているすべてのオブジェクトの名前を含む String オブジェクトの列挙を返します。
3public long getCreationTime()
このメソッドは、セッションが作成された時刻を、1970年1月1日午前0時(GMT)からのミリ秒単位で返します。
4public String getId()
このメソッドは、セッションに割り当てられた一意の識別子を含む文字列を返します。
5public long getLastAccessedTime()
このメソッドは、クライアントがセッションに関連する最後のリクエストを送信した時刻を、1970年1月1日午前0時(GMT)からのミリ秒単位で返します。
6public int getMaxInactiveInterval()
このメソッドは、Servletコンテナがクライアントアクセス時にセッションを開いたままにする最大時間間隔を秒単位で返します。
7public void invalidate()
このメソッドは、セッションを無効にし、それにバインドされているオブジェクトをすべてバインド解除します。
8public boolean isNew()
クライアントがまだセッションを知らない場合、またはクライアントがセッションに参加しないことを選択した場合、このメソッドは true を返します。
9public void removeAttribute(String name)
このメソッドは、セッションから指定された名前のオブジェクトを削除します。
10public void setAttribute(String name, Object value)
このメソッドは、指定された名前を使用してオブジェクトをセッションにバインドします。
11public void setMaxInactiveInterval(int interval)
このメソッドは、Servletコンテナがセッションを無効にするまで、クライアントリクエスト間の時間を秒単位で指定します。

セッショントラッキングの例

この例では、HttpSession オブジェクトを使用して、セッションの作成時刻と最終アクセス時刻を取得する方法を示します。セッションが存在しない場合は、リクエストを通じて新しいセッションを作成します。

package com.サンプル.test;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class SessionTrack
 */
@WebServlet("/SessionTrack")
public class SessionTrack extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        // 如果不存在 session 会话,则创建一个 session 对象
        HttpSession session = request.getSession(true);
        // 获取 session 创建时间
        Date createTime = new Date(session.getCreationTime());
        // 获取该网页的最后一次访问时间
        Date lastAccessTime = new Date(session.getLastAccessedTime());
         
        //设置日期输出的格式  
        SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    
        String title = "Servlet Session 实例 - サンプル";
        Integer visitCount = new Integer(0);
        String visitCountKey = new String("visitCount");
        String userIDKey = new String("userID");
        String userID = new String("サンプル");
        if(session.getAttribute(visitCountKey) == null) {
            session.setAttribute(visitCountKey, new Integer(0));
        }

    
        // 检查网页上是否有新的访问者
        if (session.isNew()){
            title = "Servlet Session 实例 - サンプル";
             session.setAttribute(userIDKey, userID);
        } else {
             visitCount = (Integer)session.getAttribute(visitCountKey);
             visitCount = visitCount + 1;
             userID = (String)session.getAttribute(userIDKey);
        }
        session.setAttribute(visitCountKey,  visitCount);
    
        // 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
    
        String docType = "<!DOCTYPE html>\n";
        out.println(docType +
                "<html>\n" +
                "<head><title>" + title + "</title></head>\n" +
                "<body bgcolor=\"#F0F0F0\">\n" +
                "<h1 align=\"center\">" + title + "</h1>\n" +
                 "<h2 align=\"center\">Session 信息</h2>\n" +
                "<table border=\"1\" align=\"center\">\n" +
                "<tr bgcolor=\"#949494\">\n" +
                "  <th>Session 信息</th><th>值</th></tr>\n" +
                "<tr>\n" +
                "  <td>id</td>\n" +
                "  <td>" + session.getId() + "</td></tr>\n" +
                "<tr>\n" +
                "  <td>创建时间</td>\n" +
                "  <td>" +  df.format(createTime) + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>最后访问时间</td>\n" +
                "  <td>" + df.format(lastAccessTime) + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>用户 ID</td>\n" +
                "  <td>" + userID + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>访问统计:</td>\n" +
                "  <td>" + visitCount + "</td></tr>\n" +
                "</table>\n" +
                "</body></html>"); 
    }
}

上記のServletをコンパイルし、SessionTrackweb.xml ファイルに適切なエントリを作成します。

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <servlet> 
    <!-- 类名 -->  
    <servlet-name>SessionTrack</servlet-name>
    <!-- 所在的包 -->
    <servlet-class>com.サンプル.test.SessionTrack</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SessionTrack</servlet-name>
    <!-- 访问的网址 -->
    <url-pattern>/TomcatTest/SessionTrack</url-pattern>
  </servlet-mapping>
</web-app>

ブラウザのアドレスバーにhttp://localhost:8080/TomcatTest/SessionTrackを入力します。初めて実行すると、次の結果が表示されます。

同じServletをもう一度実行すると、次の結果が表示されます。


セッションデータの削除

ユーザーのセッションデータの処理が完了したら、次のような選択肢があります。

  • 特定の属性を削除する:次のメソッドを呼び出すことができます。public void removeAttribute(String name)特定のキーに関連付けられた値を削除するためのメソッドです。
  • セッション全体を削除する:次のメソッドを呼び出すことができます。public void invalidate()セッション全体を破棄するためのメソッドです。
  • セッションの有効期限を設定する:次のメソッドを呼び出すことができます。public void setMaxInactiveInterval(int interval)セッションのタイムアウトを個別に設定するためのメソッドです。
  • ユーザーをログアウトする:servlet 2.4 をサポートするサーバーを使用している場合は、次のメソッドを呼び出すことができます。logoutWebサーバーのクライアントをログアウトし、すべてのユーザーに属するすべてのセッションを無効に設定します。
  • web.xml の設定:Tomcatを使用している場合、上記の方法に加えて、web.xml ファイルでセッションのタイムアウトを次のように設定することもできます。
  <session-config>
    <session-timeout>15</session-timeout>
  </session-config>

上記の例のタイムアウト時間は分単位で、Tomcat のデフォルトの30分のタイムアウト時間を上書きします。

Servlet 内の getMaxInactiveInterval() メソッドは、セッションのタイムアウト時間を秒単位で返します。したがって、web.xml でセッションのタイムアウトを15分に設定すると、getMaxInactiveInterval() は900を返します。

その他の拡張