1. 程式人生 > >java web--session(5)

java web--session(5)

服務端 請求 -s 頁面 serlvet gui 提示頁面 contex lag

1. Session 的創建和銷毀

page 指定的 session 屬性:

1). 默認情況下, 第一次訪問一個 WEB 應用的一個 JSP 頁面時, 該頁面都必須有一個和這個請求相關聯的 Session 對象.
因為 page 指定的 session 屬性默認為 true

2). 若把 session 屬性改為 false, JSP 頁面不會要求一定有一個 Session 對象和當前的 JSP 頁面相關聯
所以若第一次訪問當前 WEB 應用的 JSP 頁面時, 就不會創建一個 Session 對象.

3). 創建一個 Session 對象: 若 page 指定的 session 設置為 false 或 在 Servlet 中可以通過以下 API 獲取 Session 對象.

request.getSession(flag): 若 flag 為 true, 則一定會返回一個 HttpSession 對象, 如果已經有和當前 JSP 頁面關聯的 HttpSession
對象, 直接返回; 如果沒有, 則創建一個新的返回. flag 為 false: 若有關聯的, 則返回; 若沒有, 則返回 null

request.getSession(): 相當於 request.getSession(true);

4). Session 對象的銷毀:

①. 直接調用 HttpSession 的 invalidate()
②. HttpSession 超過過期時間.

> 返回最大時效: getMaxInactiveInterval() 單位是秒
> 設置最大時效: setMaxInactiveInterval(int interval)
> 可以在 web.xml 文件中配置 Session 的最大時效, 單位是分鐘.
<session-config>
<session-timeout>30</session-timeout>
</session-config>

2. 使用 HttpSession 實現驗證碼 點擊查看

1). 基本原理: 和表單重復提交一致:

> 在原表單頁面, 生成一個驗證碼的圖片, 生成圖片的同時, 需要把該圖片中的字符串放入到 session 中.
> 在原表單頁面, 定義一個文本域, 用於輸入驗證碼.

> 在目標的 Servlet 中: 獲取 session 和 表單域 中的 驗證碼的 值
> 比較兩個值是否一致: 若一致, 受理請求, 且把 session 域中的 驗證碼 屬性清除
> 若不一致, 則直接通過重定向的方式返回原表單頁面, 並提示用戶 "驗證碼錯誤"

3. 表單的重復提交

1). 重復提交的情況:
①. 在表單提交到一個 Servlet, 而 Servlet 又通過請求轉發的方式響應一個 JSP(HTML) 頁面,
此時地址欄還保留著 Serlvet 的那個路徑, 在響應頁面點擊 "刷新"
②. 在響應頁面沒有到達時重復點擊 "提交按鈕".
③. 點擊 "返回", 再點擊 "提交"

2). 不是重復提交的情況: 點擊 "返回", "刷新" 原表單頁面, 再 "提交"。

3). 如何避免表單的重復提交: 在表單中做一個標記, 提交到 Servlet 時, 檢查標記是否存在且是否和預定義的標記一致, 若一致, 則受理請求,
並銷毀標記, 若不一致或沒有標記, 則直接響應提示信息: "重復提交"

①. 僅提供一個隱藏域: <input type="hidden" name="token" value="atguigu"/>. 行不通: 沒有方法清除固定的請求參數.
②. 把標記放在 request 中. 行不通, 因為表單頁面刷新後, request 已經被銷毀, 再提交表單是一個新的 request.
③. 把標記放在 session 中. 可以!

> 在原表單頁面, 生成一個隨機值 token
> 在原表單頁面, 把 token 值放入 session 屬性中
> 在原表單頁面, 把 token 值放入到 隱藏域 中.

> 在目標的 Servlet 中: 獲取 session 和 隱藏域 中的 token 值
> 比較兩個值是否一致: 若一致, 受理請求, 且把 session 域中的 token 屬性清除
> 若不一致, 則直接響應提示頁面: "重復提交"

2. 使用絕對路徑:使用相對路徑可能會有問題, 但使用絕對路徑肯定沒有問題.

1). 絕對路徑: 相對於當前 WEB 應用的路徑. 在當前 WEB 應用的所有的路徑前都添加 contextPath 即可.

2). / 什麽時候代表站點的根目錄, 什麽時候代表當前 WEB 應用的根目錄

若 / 需要服務器進行內部解析, 則代表的就是 WEB 應用的根目錄. 若是交給瀏覽器了, 則 / 代表的就是站點的根目錄
若 / 代表的是 WEB 應用的根目錄, 就不需要加上 contextPath 了.

1. HttpSession 的生命周期:

1). 什麽時候創建 HttpSession 對象
①. 對於 JSP: 是否瀏覽器訪問服務端的任何一個 JSP, 服務器都會立即創建一個 HttpSession 對象呢?
不一定。
> 若當前的 JSP 是客戶端訪問的當前 WEB 應用的第一個資源,且 JSP 的 page 指定的 session 屬性值為 false,
則服務器就不會為 JSP 創建一個 HttpSession 對象;

> 若當前 JSP 不是客戶端訪問的當前 WEB 應用的第一個資源,且其他頁面已經創建一個 HttpSession 對象,
則服務器也不會為當前 JSP 頁面創建一個 HttpSession 對象,而回會把和當前會話關聯的那個 HttpSession 對象返回給當前的 JSP 頁面.

②. 對於 Serlvet: 若 Serlvet 是客戶端訪問的第一個 WEB 應用的資源,
則只有調用了 request.getSession() 或 request.getSession(true) 才會創建 HttpSession 對象

2). page 指令的 session=“false“ 到底表示什麽意思?

> 當前 JSP 頁面禁用 session 隱含變量!但可以使用其他的顯式的 HttpSession 對象

3). 在 Serlvet 中如何獲取 HttpSession 對象?

> request.getSession(boolean create):
create 為 false, 若沒有和當前 JSP 頁面關聯的 HttpSession 對象, 則返回 null; 若有, 則返回 true
create 為 true, 一定返回一個 HttpSession 對象. 若沒有和當前 JSP 頁面關聯的 HttpSession 對象, 則服務器創建一個新的
HttpSession 對象返回, 若有, 直接返回關聯的.

> request.getSession(): 等同於 request.getSession(true)

4). 什麽時候銷毀 HttpSession 對象:

①. 直接調用 HttpSession 的 invalidate() 方法: 該方法使 HttpSession 失效

②. 服務器卸載了當前 WEB 應用.

③. 超出 HttpSession 的過期時間.

> 設置 HttpSession 的過期時間: session.setMaxInactiveInterval(5); 單位為秒

> 在 web.xml 文件中設置 HttpSession 的過期時間: 單位為 分鐘.

<session-config>
<session-timeout>30</session-timeout>
</session-config>

④. 並不是關閉了瀏覽器就銷毀了 HttpSession.

java web--session(5)