徐岸 蘭全祥



摘要:在Web應用中會話跟蹤技術被用于保持客戶端訪問服務器時連續的狀態的常用技術.正是由于會話跟蹤技術的出現使得Web應用開發變得更加便利,并且提高了網站性能.本文將圍繞JavaWeb中的會話跟蹤技術展開及其域對象分析與討論,探討了會話跟蹤技術的背景、工作機制、相關應用以及對它們的比較.
關鍵詞:會話跟蹤技術;Cookie Session Web應用
中圖分類號:TP393.09 ? 文獻標識碼:A? 文章編號:1673-260X(2020)02-0057-03
1 引言
傳統的HTTP(HyperText Transfer Protocol)協議本身是無狀態[1],即在Web應用中多個客戶端訪問服務器端時,服務器端并不能區分各個客服端狀態信息.這種無狀態的缺陷阻礙了Web應用的發展.
為了解決HTTP無狀態的缺陷,Netscape公司推出了一項HTTP的狀態管理機制:Cookie[1].服務器使用Cookie就能跟蹤每個客戶端的訪問.但每次客戶端訪問都會傳回這些Cookie,當Cookie數量很多時,這樣無疑地增加了服務器的壓力.Session的出現就解決了這個問題.Session技術是基于Cookie技術的服務器端數據存儲技術.JSP(Java Server Pages)為了存儲客戶端信息,也提出了Request Scope和Context Scope等技術.正是利用它們不同的特性,簡化了服務器端的程序設計、增加了Web應用開發的便利性,并且提高了網站性能.
在一個客戶端中打開瀏覽器訪問某個網站開始,直到關閉這個瀏覽器的整個過程,稱為一次會話.會話技術就是記錄一次會話中客戶端的狀態與數據的技術.在Web應用開發中通常使用Cookie、Session、Request Scope、Context Scope等會話技術來存儲客戶端信息.
2 技術分析
2.1 Cookie-
當客戶端第一次訪問服務器時,服務器將用戶相關信息以Cookie的形式傳輸給客戶端[2].客戶端瀏覽器一旦接收了服務器發出的Cookie信息,就會將它存儲在瀏覽器緩沖區,即將數據存儲在客戶端中,當瀏覽器后續訪問該服務器時,都會在請求消息中將用戶相關信息以Cookie的形式發送給服務器,從而使得服務器可以分辨是哪個客戶端發送的請求(如圖1所示).
在Tomcat服務器中真正意義上創建Cookie是在org.apache.catalina.connector.Response類,通過調用generateCookieString方法將Cookie對象構造成一個遵循Cookie語法規則的字符串,并將這個字符串添加到MimeHears中,從而構建HTTP響應頭返回至客戶端.在Servlet中提供了setPath(String path)、setMaxAge(int expiry)等方法來設置HTTP響應頭Set-Cookie字段的屬性項.其中setPath(String path)是設置Cookie被允許訪問的路徑,如果不設置攜帶路徑,那么該Cookie信息會在訪問產生該Cookie的Web資源所在的路徑都攜帶cookie信息.在Servlet中使用javax.servlet.http.HttpServletRequest類中的getCookies()方法獲得一個Cookie的對象數組;使用javax.servlet.http.HttpServletResponse類中的addCookie(Cookie cookie)方法向客戶端發送Cookie
2.2 Session
Session技術是基于Cookie技術的服務器端數據存儲技術,即Session需要借助于Cookie所存儲的客戶唯一性標識JSESSIONID,即從客戶端傳輸一個NAME為JSESSIONID的Cookie給服務器,而這個JSESSIONID是客戶端第一次訪問服務器時所生成.在一次會話中客戶端只要傳回JSESSIONID給服務器,Tomact服務器就會選擇與之對應的Session對象為其服務[5].(如圖2所示)
當JSESSIONID傳入Tomact服務器中時,Tomact服務器中會將傳入的JSESSIONID解析為Session ID.當使用request.getSession()獲得HttpSession對象時,服務器就是利用Session ID判斷在Session容器中是否存在與之對應的HttpSession對象.如果有就返回該HttpSession對象;如果沒有,服務器就會創建一個新的HttpSession對象,并將這個對象添加到org.apache.catalina.Manager類的Session容器中.其中Manager類的功能是負責管理所有Session的生命周期、服務器關閉時Session將被序列化到磁盤、Session過期回收等.
2.2 Request Scope
Request是在Servlet方法調用前由Tomact服務器創建,Tomact服務器接到請求后,首先會創建org.apache.coyote.Request對象,Tomact服務器經過對此對象解析后會交給用戶線程去處理這個請求,同時會創建org.apache.connector.Request對象,這個對象將貫穿Servlet容器直至傳給Servlet.正是由于這樣的特性,Requese中存儲的數據可以在一次請求鏈中多次獲取,直至請求結束.
2.4 Context Scope
Context Scope的數據在Tomact服務器中是存放在ServletContext中,而在Servlet中獲得的ServletContext對象實際是ApplicationContextFacade對象,ApplicationContextFacade和ServletContext使用的是門面設計模式,它們可以在Context容器中獲取屬于他們的數據,并且對數據起到封裝作用.在服務器中ServletContext是在Tomact服務器啟動時就會被服務器創建,直至服務器關閉或該Web應用被移除.ServletContext中的數據被所有客戶端共享.
3 應用
3.1 通過Cookie保存用戶信息
當用戶在其所信任的客戶端登錄Web應用時,在服務器端對該用戶的登錄信息進行處理.那么該用戶在后續訪問該網站可直接以登錄狀態直接訪問.實現的方法是將用戶登錄信息保存在Cookie中,并控制Cookie的有效期,下次訪問網站時服務器驗證Cookie中的用戶信息即可.
但是Cookie是可以在瀏覽器明文查看的,Web應用中通常情況下,不會把密碼等重要的用戶信息保存到Cookie中.在上述條件下的實現方式:在服務器中將用戶的賬號通過MD5算法進行加密,將加密后的賬號和用戶賬號一起保存到Cookie中(Java實現代碼如下).用戶在后續登錄時驗證賬號的加密規則是否正確即可.
String autoLogin = request.getParameter("autoLogin");
if ("true".equals(autoLogin)) {
String account = request.getParameter("account");
String ssid = MD5Utils.MD5(account);
Cookie accountCookie = new Cookie("userID", account);
accountCookie.setMaxAge(30*60);
Cookie ssidCookie = new Cookie("ssid", ssid);
ssidCookie.setMaxAge(30*60);
response.addCookie(accountCookie);
response.addCookie(ssidCookie);
response.sendRedirect(request.getRequestURI() + "?" +System.currentTimeMillis());
}
3.2 利用Session防止表單重復提交
在Web應用中很多時候存在用戶重復提交表單的情況,如由于用戶操作不當多次提交表單;用戶網速過慢,不斷重復刷新提交表單;惡意用戶通過相關程序惡意重復提交表單等.上述非常規操作都會導致表單的重復提交.表單的重復提交可能會造成服務器端的數據重復,增加服務器的壓力,影響服務器的性能,甚至嚴重的話,可能會對服務器造成宕機的情況,因此Web應用中防止表單重復提交的技術顯得尤為重要.
利用Session防止表單重復提交,需要在該表單中增加一個隱藏表單項.如下面JSP代碼所示: