前言
前面的博客說到了servlet的接口和類,這次來說下Servlet的會話跟蹤技術。
正文
【會話跟蹤】概念 |
Http 協議是一個無狀態的協議,當客戶端瀏覽器一次請求到來,服務器端返回響應之後,兩者之間的連接就斷開了,服務器端並不保存每次的連接信息,如何維繫客戶端和服務器之間的連接,這就需要會話跟蹤技術的支持。會話跟蹤技術主要用來web服務器端跟蹤客戶狀態,維護客戶端和服務器之間的連接。
常見的會話跟蹤技術 |
- Cookie
第一次請求時服務器主動發一小段信息給瀏覽器(即Cookie),下次請求時瀏覽器會自動附帶這一小段信息發送給服務器,服務器讀取Cookie 識別用戶。 - 隱藏的表單域
將sessionID 隱藏在html表單中提交到服務器,這個sessionID在瀏覽器頁面不顯示。
非常適合不需要大量數據存儲的會話應用 - URL重寫
在url 結尾附加sessionID(sessionID) 標識,服務器通過會話ID 識別不同用戶。 - Session
服務器爲每個用戶創建一個Session對象保存到內存中,生成一個sessionID放入Cookie中發送給瀏覽器,下次訪問時sessionID會隨着Cookie傳回來,服務器再根據sessionID找到對應Session對象(Java領域特有)。
Cookie |
現在所有主流瀏覽器都支持Cookie ,以至於HTTP協議爲它定義了一些新的HTTP首部Set-cookie 。
Cookie 的規範
- Cookie 通過請求頭/響應頭 在服務器與客戶端之間傳輸,大小限制爲4KB;
- 一臺服務器在一個客戶端最多保存20個Cookie;
- 一個瀏覽器最多保存300個Cookie;
Cookie類 及API : 訪問鏈接
Servlet中的Cookie的使用:
package com.dmsd.servlet;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class CookieTest extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
response.setContentType("text/html;charset = gb2312");
request.setCharacterEncoding("gb2312");
PrintWriter out = response.getWriter();
String username = request.getParameter("userName");
//創建cookie實例,需要傳入屬性名稱和屬性值,兩個都是String類型
Cookie userCookie = new Cookie("userName",userName);
Cookie pwdCookie = new Cookie("pwd",request.getParameter("pwd"));
if(request.getParameter("saveCookie") != null && request.getParameter("saveCookie").equals("Yes")){
userCookie.setMaxAge(7*24*60*60);// 設置Cookie的保存時間
pwdCookie.setMaxAge(7*24*60*60);
out.print("你的信息已經保存在Cookie中");
else{
userCookie.setMaxAge(0);
pwdCookie.setMaxAge(0);
out.print("你的信息已經從Cookie中刪除");
}
response.addCookie(userCookie);// 發送Cookie到客戶端
response.addCookie(pwdCookie);
}
}
}
侷限:
Cookie是鍵值對存儲結構,只能保存String類型的數據;
如果用戶在瀏覽器端設置了禁用Cookie,它就失效了;
Cookie 不支持中文,需要在存儲時編碼,取出時解碼;
因爲Cookie將信息保存到客戶端,所以會有安全性的問題;
隱藏的表單域 |
<input type="hidden" name="sessionid" value="12345">
屬性解釋:
type="hidden"定義隱藏域;
name屬性定義隱藏域的名稱,要保證數據的準確採集,必須定義一個獨一無二的名稱;
value屬性定義隱藏域的值
例如:<input type=”hidden” name=”ExPws” value=”dd”>
侷限:
當客戶端點擊常規的超文本鏈接時導致表單不會提交,這時候隱藏的表單域也就失效了。
URL重寫 |
上面提到,用戶可能關閉瀏覽器的Cookie功能,這樣基於Cookie的Session 技術就不能用了,Sun公司提供了一種替代性的方案,就是URL重寫,將本來保存在Cookie中的用於標識不同客戶端的SessionID放在url後面,這樣,即使用戶關閉了瀏覽器的Cookie功能,Session還是能正常使用,服務器端通過SESSIONID 關鍵字來獲取會話值。
實現方式:
// 1、手動方式
url;jsessionid = ……
//2、api方式
// 進行所有URL 重寫
encodeURL(java.lang.String url)
// 進行重定向URL 重寫
encodeRedirectURL(java.lang.String url)
舉個例子
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//創建session
HttpSession session = request.getSession();
session.setAttribute("greeting", "hello");
System.out.println("sessionID :" + session.getId());
// 請求url,將瀏覽器設置cookie 禁用,纔會有jsessionid
String url = "/SessionTest/session";
String newUrl = response.encodeRedirectURL(url);
System.out.println("newURL:" + newUrl);
}
運行結果:
Session |
服務器給每個客戶端分配一個不重複的ID號用來區分不同的客戶端,而對應各個客戶需要保存的數據保存在服務器的內存中,這樣,每個客戶端Cookie 中只保存一個ID號,而將實際需要保存的數據放在服務器內存中,服務器可以存放的對象就突破了String類型的限制,數據不需要寫到客戶端的文本中。
在所有的會話跟蹤技術中, Session是功能最強大,最多的. 每個用戶可以沒有或者有一個HttpSession對象, 並且只能訪問他自己的Session對象。
HttpSession 是Java Servlet API 中提供的對Session機制的實現規範,這是個接口,建立在URL 重寫或Cookie 的基礎上,由Servlet容器來實現。
HttpSession的常用方法
方法 | 說明 |
---|---|
Object getAttribute(String name) | 從session中返回指定name的屬性的值,如果指定的name屬性不存在,則返回null |
Enumeration getAttributeNames() | 返回session中所有的屬性名稱,並且封裝在Enumeration對象中返回 |
void setAttribute(String name,Object value) | 在session中設置名稱爲name的屬性,屬性值爲一個對象value |
void removeAttribute(String name) | 從session中指定名稱爲name的屬性 |
void invalidate() | 廢除這個session,並且釋放session關聯的對象 |
Boolean isNew() | 用於檢測此session是否爲新創建的 |
void setMaxInactiveInterval(int time) | 設置在沒有訪問的情況下,會話在服務器端被自動廢除的時間,單位是秒 |
舉個例子
// 登錄操作類
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userName = request.getParameter("userName");
String password = request.getParameter("password");
//獲取session對象
HttpSession session = request.getSession();
//如果用戶名和密碼都是“admin”就登錄成功
if("admin".equals(userName) && "admin".equals(password)) {
//把用戶信息保存到session中
session.setAttribute("userName", userName);
session.setAttribute("msg", "登錄成功");
request.getRequestDispatcher("/Result").forward(request, response);
}else{
request.getRequestDispatcher("/Login.html").forward(request, response);
}
}
// 登錄之後處理類
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取session
HttpSession session = request.getSession();
String userName = (String)session.getAttribute("userName");
if(userName == null){
request.getRequestDispatcher("Login.html").forward(request, response);
return;
}
}
總結
Sevlet 中的會話跟蹤機制先介紹到這裏,感謝您的閱讀!