HttpSession簡介及Session驗證碼的實現
1. HttpSession 的生命週期
1)什麼時候創建HttpSession對象
①對於JSP:是否瀏覽器訪問服務器的任何一個JSP,服務器都會立即創建一個HttpSession對象呢?
不一定
Ø 若當前的JSP訪問的第一個資源,且page指定的session屬性值爲false,則不創建
Ø 若不是第一個,但是其他頁面已經創建一個HttpSession對象,也不會就創建新的,用以前的
②對於Servlet:若Servlet是客戶端訪問的第一個WEB應用資源,則指有調用了request。getSession()或request.getSession(true)纔會創建HttpSession對象
2)page中的Session=-“false”到底表時什麼意思?
Ø 當前JSP頁面禁用Session隱含變量!但可以使用其他的顯示的HttpSession對象
Ø Servlet中可以通過以下 API 獲取 Session 對象
request.getSession(flag):
若 flag 爲 true, 則一定會返回一個HttpSession 對象, 如果已經有和當前 JSP 頁面關聯的 HttpSession對象, 直接返回; 如果沒有, 則創建一個新的返回.
flag 爲 false: 若有關聯的, 則返回; 若沒有, 則返回 null
request.getSession():相當於 request.getSession(true);
3). 創建一個 Session 對象: 若 page 指定的 session 設置爲 false 或在 Servlet 中可以通過以下 API 獲取 Session 對象.
request.getSession(flag):若 flag 爲 true, 則一定會返回一個HttpSession 對象, 如果已經有和當前 JSP 頁面關聯的 HttpSession
對象, 直接返回; 如果沒有, 則創建一個新的返回.flag 爲 false: 若有關聯的, 則返回; 若沒有, 則返回 null
request.getSession():相當於 request.getSession(true);
HttpSession session = request.getSession(); out.print(session.getId()); session.invalidate(); |
每次不一樣 |
4). Session 對象的銷燬:
①. 直接調用 HttpSession 的 invalidate()
②.HttpSession 超過過期時間.
> 返回最大時效:getMaxInactiveInterval() 單位是秒
> 設置最大時效:setMaxInactiveInterval(int interval)
可以在 web.xml 文件中配置 Session 的最大時效, 單位是分鐘.
<session-config> <session-timeout>30</session-timeout> </session-config> |
③. 卸載當前 WEB 應用.
注意: 關閉瀏覽器不會銷燬 Session!
重新登錄和註銷方法實現 |
Login.jsp |
<% Object username = session.getAttribute("username"); if(username==null){ username=""; } %> <form action="hello.jsp" method="post"> username:<input type="text" name="username" value="<%=username%>"/> <input type="submit" value="Submit"/> </form> |
Hello.jsp |
Hello:<%=request.getParameter("username") %>
<%--重新登錄有兩種方式 <a hr ef="Zhuxiao.jsp?username=<%=request.getParameter("username") %>">重新登錄</a> --%> <!-- session 可以跨頁面--> <% session.setAttribute("username", request.getParameter("username")); %> <a href="login.jsp">重新登錄</a> <a href="logout.jsp">註銷</a> |
Logout.jsp |
Bye:<%=session.getAttribute("username") %> <br><br>
<a href="login.jsp">重新登錄</a> <% session.invalidate(); %> |
注:頁面組織cookie時的重新登錄方法——URL重寫 |
<a href=response.encodeURL("login.jsp")>重新登錄</a> |
或者 <a href=response.encodeRedirectURL("login.jsp")>重新登錄</a> |
2. / 什麼時候代表站點的根目錄, 什麼時候代表當前 WEB 應用的根目錄
1)當前WEB應用的根路徑:http://localhost:8080/contextPath
若/ 交由Servlet容器來處理
其中的ContextPath可由request或application的getContextPath方法來獲取
Ø 請求轉發request.getRequestDispatcher(“/path/b.jsp”).forward(request,response);
Ø Web.xml中的<selrvlet-mapping>
Ø 各種定製標籤中的/
2)WEB站點的根路徑:http://localhost:8080/
交由瀏覽器來處理
Ø 超鏈接<a href=”/TestServlet”>TO B Page</a>
Ø 表單中的action:<form action=”/login.jsp”>
Ø 請求重定向:response.sendRedirect(“/a.jsp”)
3. 表單的重複提交
1). 重複提交的情況:
①. 在表單提交到一個 Servlet, 而 Servlet 又通過請求轉發的方式響應一個JSP(HTML) 頁面,
此時地址欄還保留着 Serlvet 的那個路徑, 在響應頁面點擊 "刷新"
②. 在響應頁面沒有到達時重複點擊 "提交按鈕".
③. 點擊 "返回", 再點擊 "提交"
2). 不是重複提交的情況: 點擊 "返回", "刷新" 原表單頁面, 再 "提交"。
3). 如何避免表單的重複提交: 在表單中做一個標記, 提交到 Servlet 時, 檢查標記是否存在且是否和預定義的標記一致, 若一致, 則受理請求,並銷燬標記, 若不一致或沒有標記, 則直接響應提示信息: "重複提交"
①. 僅提供一個隱藏域: <inputtype="hidden" name="token" value="atguigu"/>. 行不通: 沒有方法清除固定的請求參數.
②. 把標記放在 request 中. 行不通, 因爲表單頁面刷新後, request已經被銷燬, 再提交表單是一個新的 request.
③. 把標記放在 session 中. 可以!
> 在原表單頁面, 生成一個隨機值 token
> 在原表單頁面, 把 token 值放入session 屬性中
> 在原表單頁面, 把 token 值放入到隱藏域中.
> 在目標的 Servlet 中: 獲取 session 和隱藏域中的 token 值
> 比較兩個值是否一致: 若一致, 受理請求, 且把 session 域中的 token 屬性清除
> 若不一致, 則直接響應提示頁面: "重複提交"
4. 使用 HttpSession 實現驗證碼
1). 基本原理: 和表單重複提交一致:
> 在原表單頁面, 生成一個驗證碼的圖片, 生成圖片的同時, 需要把該圖片中的字符串放入到 session 中.
> 在原表單頁面, 定義一個文本域, 用於輸入驗證碼.
> 在目標的 Servlet 中: 獲取 session 和表單域中的驗證碼的值
> 比較兩個值是否一致: 若一致, 受理請求, 且把 session 域中的驗證碼屬性清除
> 若不一致, 則直接通過重定向的方式返回原表單頁面, 並提示用戶 "驗證碼錯誤"