サーブレットベース_0400_Session原理の探究

9248 ワード

本文はSessionを討論する
一.セシオンって何?
Sessionはサーバー側のメモリで、中にデータを入れることができます.Sessionのnameは文字列でなければなりません.値は任意のオブジェクトです.
二.Sessionの実現原理:
Sessionの実現方式は2種類ある:(企業常問)a.クライアントがCookieをサポートする場合、SessionはCookieによって実現され、SessionIdをCookieに保存するb.クライアントがCookieをサポートしない場合、プログラミングによって実現しなければならない.URL(encodingURL()メソッド)を書き換えるa種類の実現方式:sessionIdをCookieに保存し、一時的なCookieに保存し、時間を設定する必要がない.ブラウザが閉じると、このsessionIdが保存されているCookieはすぐに消えます.ウィンドウが閉じているので、このSessionには二度とアクセスしません.bつの実装方法:response.EncodingURL()実装,すなわちSessionを使用する必要があるページごとにハイパーリンクにresponseを付ける.encodingURL("urlString");[encodingURL()の役割は2つあります.1つはトランスコードで、もう1つはurlの後ろにsessionIDを付けます.]
次に、この2つの実装方法について実験を行います.
実験a.デフォルトCookie有効化
//SessionInfoServlet.java
package com.servlet;

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

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

public class SessionInfoServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = response.getWriter();
		
		HttpSession session = request.getSession(true);
		pw.println("Session Information:"+"<br />");
		pw.println("New Session:"+session.isNew()+"<br />");
		pw.println("SessionId:"+session.getId()+"<br />");
		pw.println("Session created time:"+new Date(session.getCreationTime())+"<br />");
		pw.println("Session last access time:"+new Date(session.getLastAccessedTime())+"<br /><br />");
		
		pw.println("Request Information:"+"<br />");
		pw.println("SessionID from request:"+request.getAttribute("JSESSIONID")+"<br />");
		pw.println("Session via Cookie:"+request.isRequestedSessionIdFromCookie()+"<br />");
		pw.println("Session via written URL:"+request.isRequestedSessionIdFromUrl()+"<br />");
		pw.println("Valid Session:"+request.isRequestedSessionIdValid()+"<br />");
		pw.println("<a href='ShowCookies'>Show ALL Cookies</a>"+"<br />");
		pw.println("<a href='"+response.encodeURL("SessionInfoServlet")+"'>refresh</a>");
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doGet(req, resp);
	}
	
}

//ShowCookies.java
package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ShowCookies extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = response.getWriter();
		Cookie[] cookies = request.getCookies();
		if(cookies!=null){
			for(int i=0;i<cookies.length;i++){
				pw.println(cookies[i].getName()+"  :  "+cookies[i].getValue()+"<br />");
			}
		}else{
			pw.println("  Cookie!");
		}
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doGet(req, resp);
	}
	
}

1.この2つのページを構成し、ブラウザのCookieが使用できることを確認する.次に、SessionInfoServiceページにアクセスし、次のように出力します.
Session Information:  New Session:true  SessionId:21BF726DBA2132F44A0514EA90DCAB66  Session created time:Wed Sep 28 20:43:04 CST 2011  Session last access time:Wed Sep 28 20:43:04 CST 2011  Request Information:  SessionID from request:null  Session via Cookie:false  Session via written URL:false  Valid Session:false Show ALL Cookies[ハイパーリンク]refresh[ハイパーリンク]
2.再度更新し、次のように出力します.
Session Information:  New Session:false  SessionId:21BF726DBA2132F44A0514EA90DCAB66  Session created time:Wed Sep 28 20:43:04 CST 2011  Session last access time:Wed Sep 28 20:43:04 CST 2011  Request Information:  SessionID from request:null  Session via Cookie:true  Session via written URL:false  Valid Session:true Show ALL Cookies[ハイパーリンク]refresh[ハイパーリンク]
3.後で更新して、SessionIDは不変で、last access timeだけが変化して、その他のすべての値はすべて変化しないで、sessionは発効して、それからShow ALL Cookiesをクリックして、発見します:
JSESSIONID  :  21BF726DBA2132F44A0514EA90DCAB66
Cookieが存在します.
クライアントがCookieを無効にしていない場合、Sessionは直接Cookieに基づいて実現され、サーバ側でSessionを作成すると、サーバはブラウザごとにSessionIDを指定し、クライアントの一時Cookieに存在し、クライアントが再びサーバにアクセスすると、サーバはクライアントのSessionIDを検証し、元のSessionを見つけることができる.これでセシオンが実現
実験b.Cookieを無効にする
1.まずCookieを無効にします(この機能はブラウザのサポートが必要です.この実験はブラウザと関係があります.あるブラウザはCookieを禁止できないので、私はOperaを使っています[IE 8、FireFox、Chroomはだめのようです])
2.SessionInfoServiceページにアクセスし、次のように出力します.
Session Information:  New Session:true  SessionId:7FA232B7C56545ABA6ADE42CE58665EC  Session created time:Wed Sep 28 20:55:55 CST 2011  Session last access time:Wed Sep 28 20:55:55 CST 2011  Request Information:  SessionID from request:null  Session via Cookie:false  Session via written URL:false  Valid Session:false Show ALL Cookies[ハイパーリンク]refresh[ハイパーリンク]
3.次に更新すると、コンテンツのSessionIDが変更されていることがわかります.
Session Information:  New Session:true  SessionId:35247C4D2BC096F5C76122EA16DA9CBE  Session created time:Wed Sep 28 20:57:13 CST 2011  Session last access time:Wed Sep 28 20:57:13 CST 2011  Request Information:  SessionID from request:null  Session via Cookie:false  Session via written URL:false  Valid Session:false Show ALL Cookies refresh
しかもどんどんリフレッシュして変化していくので、このときのSession機能は使えない、つまりCookieを無効にした場合、Session機能はCookieに基づいて実現できないということですが、どうすればいいのでしょうか?
URLを書き換え、各ハイパーリンクにresponseを付ける.encodingURL("url");たとえば、例のrefreshをクリックすると、ハイパーリンクが見つかります.http://localhost:8080/Servlet_0400_Session/servlet/SessionInfoServlet;jsessionid=35247 C 4 D 2 BC 096 F 5 C 76122 EA 16 DA 9 CBEの後ろにjsessionid=......;これで同様にSessionIDをサーバに転送することができ,サーバも同様にそのSessionを見つけることができ,Session機能も実現する.
まとめ:どちらの場合でもセッションが実現できる以上、いったいどのような方法で実現するのでしょうか.
緊急時には、クライアントのCookieが有効であることをデフォルトで設定することができます.多くの大手企業がこのようにしています.例えば、新浪など、クライアントはCookieを開くべきです.そうしないと、プログラムを書くのに疲れませんか.Cookieを開いてこそ、私たちのサービスを使用することができます.もちろん、時間が十分な場合、プログラムをより丈夫にし、より完璧にし、responseも加えなければならない.encodingURL(".."),多くの有名な会社がこのようにしています.Sessionページを使用する必要があるURLごとに、マイクロソフト、sun、oracleなどが追加されています.
三.SessionとCookieの違いと連絡:
1.Sessionはサーバー側に存在し、ほとんどのSessionアプリケーションはCookieベースであり、Sessionには任意のデータを格納することができ、Sessionは1つのブラウザの複数のラベル、複数のページで共有することができ、布団ウィンドウで共有することもできるが、新しいブラウザで共有することはできない.この一時的なCookieは現在のブラウザとのメモリしか存在しないため、新しいブラウザは同じメモリの一部を共有しません
2.Cookieはクライアントのテキストファイルであり、ブラウザメモリの一時的なCookieである可能性もある[ファイルに書き込まない].ファイルに書き込まれたCookieは複数のブラウザで共有され、期限が切れた後に自動的にクリアされ、一般的に2週間以内に自動的にログインするなどの機能に用いられる
3.Sessionはパスの問題がなく、同じウェブアプリケーションの任意のページで使用することができます.Cookieにはパスの問題があり、servlet/jspは同じレベルのパスまたはそのサブパスにしかアクセスできません.
四.Sessionがなぜ経路問題が存在しないのかを検討する[CookieベースのSession機能のみを議論する]
SessionはCookieに基づいて実現されるため、サーバはクライアントから送られてきたSessionIDを取得してこそそのSessionを見つけることができる.では、現在Cookieにはパスの問題がある.このservlet/jspは親パスの下でCookieにアクセスできないのではないかと仮定すると、そのSessionIDが手に入らない.Session機能は実現できないのではないか.
次の実験を行います.
1.web.xmlは以下のように変更されました://SessionInfoServiceのパスをservletの下に、ShowCookiesを親のパスの下に、ShowCookiesがそのCookieにアクセスできないように
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	
	<servlet>
		<servlet-name>SessionInfoServlet</servlet-name>
		<servlet-class>com.servlet.SessionInfoServlet</servlet-class>
	</servlet>  	
	<servlet-mapping>
		<servlet-name>SessionInfoServlet</servlet-name>
		<url-pattern>/servlet/SessionInfoServlet</url-pattern>
	</servlet-mapping>
	
	<servlet>
		<servlet-name>ShowCookies</servlet-name>
		<servlet-class>com.servlet.ShowCookies</servlet-class>
	</servlet>  	
	<servlet-mapping>
		<servlet-name>ShowCookies</servlet-name>
		<url-pattern>/ShowCookies</url-pattern>
	</servlet-mapping>
	
</web-app>
2.まずCookieの有効化、アクセスを保証しますhttp://localhost:8080/Servlet_0400_Session/servlet/SessionInfoServletを選択し、http://localhost:8080/Servlet_0400_Session/ShowCookiesああ、発見ページ出力:JSESIONID:21 BF 726 DBA 2132 F 44 A 0514 EA 90 DCAB 66、このセッションIDはやはりアクセスして、つまりサーバーはやはりそのSessionIDを手に入れて、まさかこのCookieはservletパスの下に存在しないで、Cookieマネージャを開けて、確かにこのCookieはservletサブパスの下に存在しないことを発見して、直接ルートディレクトリの下に存在して、なるほど、SessionIDはCookieに基づいて実装されているが、Cookieのパスに基づいているのではなく、ルートディレクトリの下に直接保存されている[もちろんメモリ内]