Day12--Servlet中的Cookie+Session
Servlet接收不同的表單資料
<form action="/s1" method="post"> <!-- name 是引數名 --> <input type="date" name="birthday" value="2018-09-15"> <hr> 男 <!-- MALE FEMALE --> <input type="radio" name="sex" value="男" checked> 女 <input type="radio" name="sex" value="女"> <hr> 唱歌<input type="checkbox" name="hobby" value="1"> 跳舞<input type="checkbox" name="hobby" value="2"> 睡覺<input type="checkbox" name="hobby" value="3"> 玩遊戲<input type="checkbox" name="hobby" value="4"> <hr> <!-- option 標籤如果不提供 value屬性, 把標籤之間的文本當成value 如果提供了value屬性,以value為準 --> <select name="city"> <option>北京</option> <option>天津</option> <option value="shanghai">上海</option> <option>武漢</option> </select> <hr> 個人簡介: <textarea name="intro" cols="30" rows="10"></textarea> <input type="submit" value="提交"> </form>
@WebServlet(urlPatterns = "/s1") public class Servlet1 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 處理漢字亂碼 req.setCharacterEncoding("utf-8"); // 1) 日期型別的接收,需要注意轉換字串為java中的Date型別 String birthday = req.getParameter("birthday"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { Date date = sdf.parse(birthday); System.out.println(date); } catch (ParseException e) { e.printStackTrace(); } // 2) 處理單選按鈕 String sex = req.getParameter("sex"); System.out.println(sex); // 3) 處理複選框, 注意處理null值(都沒有勾選時,就是null值) String[] hobbies = req.getParameterValues("hobby"); if(hobbies != null) { for (String hobby : hobbies) { System.out.println(hobby); } } // 4)處理下拉列表 String city = req.getParameter("city"); System.out.println(city); // 5)處理文字域 String intro = req.getParameter("intro"); System.out.println(intro); } }
JSP的九大內建物件: 無需宣告即可使用的物件
request: 代表請求物件(可以獲取請求引數,將變數儲存到 request作用域 中)
request的作用域只在一次請求內有效
response: 代表響應物件(返回響應)
out: 代表響應的字元輸出流
pageContext: 代表頁面上下文物件,可以間接獲得request等物件,並可以將變數存入page作用域
session: 代表會話物件
,變數的作用範圍是 一次會話 內有效application: 代表一個應用程式物件,變數的範圍是 整個應用程式 內有效
page: 當前 jsp頁面(相當於 this) page的作用域僅在當前頁面內有效
config: jsp的配置資訊
exception: 代表的是異常資訊物件,只有當 isErrorPage=" true " 時,才有效
JSP的四大作用域:
作用域名 作用範圍 說明 page 僅限當前頁面 從請求到達頁面開始,請求離開這一頁面為止 request 限一次請求 從請求到達伺服器開始,響應返回為止 session 限一次會話 從一個瀏覽器客戶端訪問,伺服器呼叫request.getSession()開始,一直到session.invalidate()或自動超時為止 application 限一次應用執行 從應用程式啟動開始,應用程式結束執行為止
HTTP的無狀態:
http的無狀態是指請求與請求之間不儲存狀態,即伺服器端不會主動記住上一次請求是誰發的,和這次請求有沒有聯絡。如果伺服器要記住上一次請求的相關資訊,必然需要將這些資訊儲存在伺服器端,增大了伺服器壓力。要知道web應用的一個主要目標是要同時為大量的客戶端提供服務,因此讓伺服器端無狀態,意味著對所有客戶端的處理一視同仁,提高了伺服器的併發能力。(如果需要儲存狀態,可以利用cookie,session等技術來實現)
Cookie:用來記錄多次請求之間的聯絡,儲存伺服器的狀態
用來 在瀏覽器端 儲存伺服器狀態資訊的鍵值對,cookie一般應該 由伺服器 產生
Cookie的使用:瀏覽器在每次傳送請求時,都會將該域名下的所有Cookie傳送給伺服器
1) 建立cookie 物件: Cookie c = new Cookie("名字","值"); // 儲存的是鍵值對的資訊
2)response.addCookie( c ); // 通過響應物件,把建立好的 Cookie 返回給瀏覽器
3)c.setMaxAge( 整數 );// 設定Cookie的生存時間,單位是 秒 沒有設定壽命的是會話cookie瀏覽器關閉就刪除
c.setMaxAge( 0 ); // 手動刪除此Cookie
獲取Cookie:
Cookie[] c = request.getCookies(); // 獲取此次請求中該域名下的所有Cookie
傳送Cookie時的中文亂碼:
解決辦法: 編碼:URLEncoder.encode(中文,“utf-8”);
解碼:URLDecoder.decode(編碼後的內容,"utf-8");
// 前後編碼格式要一致
EL表示式獲取Cookie的值:
語法: ${cookie.cookie的名字.value};
Cookie的限制:
瀏覽器的每個域名一般包含 30~50 個 Cookie
每個Cookie的大小約為 4k
Session: (會話) 可以在同一個客戶端的多次請求間儲存和共享資訊 這些資訊被儲存伺服器端
session的建立:
// 首次呼叫getSession方法就是建立session物件 // 後續再呼叫getSession方法是獲取第一次建立好的session物件
HttpSession session = req.getSession();
session的使用:
存入內容: session.setAttribute("變數名",值);
取出內容: Object o = session.getAttribute("變數名");
刪除內容: Object o = session.removeAttribute("變數名");
使session失效: session.invalidate(); (會清空session的所有內容)
在JSP頁面中獲取 session 的值:
格式: ${ sessionScope.變數名 }
session的生命週期:
建立: 首次呼叫 request.getSession(); / request.getSession( true );
銷燬: 主動銷燬: session.invalidate();
被動銷燬: session的預設生存時間是 30 分鐘,如果客戶端距離上次請求時間超過此過期時間後, tomcat容器會呼叫session.invalidate()方法讓session過期
******注意:
- 關閉瀏覽器並不會立刻結束session,瀏覽器關閉會導致丟失與此session的聯絡 (瀏覽器關閉會刪除JSESSIONID這個會話cookie),因此session還是會在30分鐘後才失效
- 如何在HttpSession過期的時候,清理你在HttpSession中儲存的物件的資源佔用? 伺服器可以在session過期時自動釋放它所佔用的資源。但如果使用者沒有主動點選
登出
功能來呼叫session.invalidate()方法,而是直接關閉了瀏覽器,那麼必須再等待一段時間(預設30分鐘)session才會銷燬,比較浪費伺服器資源。 一種解決方法是在客戶端網頁中通過js加入onunload或onbeforeunload事件,此事件會在瀏覽器(或標籤頁)關閉時觸發,這時向伺服器傳送一個登出請求來結束session
Session的實現原理: session必須針對同一個瀏覽器,才能實現在對個請求間共享資訊
每個使用者訪問伺服器時,伺服器會為他們建立一個獨立的session
1) 首次建立 session 物件,伺服器會建立一個 “JESSIONID=值 ” 的 唯一標識 cookie ,
隨著 瀏覽器的響應,返回給傳送請求的瀏覽器
2) 該瀏覽器拿到此cookie後,之後再次發生請求時會根據這個 cookie 去尋找對應的 session ,由此建立連線
3) JSESSIONID 屬於會話 cookie, 一旦瀏覽器關閉,此cookie就會消失,連線就會中斷
URL重寫 :當瀏覽器禁用了Cookie,仍希望能維持會話跟蹤,這時候需要使用URL重寫技術
- 瀏覽器傳送第一次請求給localhost伺服器後,伺服器呼叫request.getSession()建立新的HttpSession物件,假設它的id=123
- 當這次響應返回時,需要對頁面中所有
表單提交的路徑
,超連結的路徑
之後都加上;jsessionid=123
,生成這些路徑字尾可以通過呼叫HttpServletResponse.encodeURL()
來完成- 當提交表單請求到達伺服器後,伺服器會解析請求地址後面
;jsessionid=123
部分,根據它找到正確的HttpSession物件- 當點選超連結請求到達伺服器後,伺服器會解析請求地址後面
;jsessionid=123
部分,根據它找到正確的HttpSession物件
Cookie 和 Session 之間的 聯絡 與 區別:
cookie 和 session 都是使用 鍵值對 的方式來為 客戶端 儲存一些 伺服器 的資訊
區別:
1)cookie是儲存在 瀏覽器端 的
session是儲存在 伺服器端 的
2)每個客戶端為某一網站儲存的 cookie 資訊都是有限制的,一般為 30~50 個 cookie,每個大小為 4k 左右
而session存在於伺服器端,對儲存的大小沒有限制,但由於伺服器是為多個使用者進行服務的, 所以不建議儲存過多的session資訊,可以將資訊儲存在 資料庫 / 快取 中
3)安全性: cookie儲存在瀏覽器端很容易被洩露,而且會被截獲的風險很大,而 session就相對更為 安全
4)生命週期:
cookie的生命週期是 在瀏覽器關閉之前都有效
session的生命週期則更短一些,如果兩次請求之間間隔的時間大於 30 分鐘,則會自動銷燬
或者是 呼叫 session.invalidate() 方法 ,session會立即銷燬
5)cookie的內容資料型別只能是 字串,而session則可以是 任意型別 的資料
聯絡: session 與 客戶端 的聯絡 是通過 cookie 實現的
當伺服器為某一客戶端首次建立session時,會將一個JSESSIONID=唯一值
的會話cookie返回給客戶端瀏覽器 ,當瀏覽器向此伺服器傳送接下來的請求時,會攜帶此JSESSIONID=唯一值
的cookie,伺服器從而可以通過它找到此客戶端對應的session
請求重定向: response.sendRedirect(" 目標路徑 ")
請求轉發: request.getRequestDispatcher(" 目標路徑 ").forword(request,response)
請求轉發 和 重定向的區別:
1) 請求轉發是 同一次請求,跳轉發生在伺服器內部
重定向 是 兩次請求,第一次請求,伺服器返回一個 302 狀態碼 和 location: 目標地址
第二次請求時,根據返回的 location 的目標地址 跳轉
2) 請求轉發時,位址列的訪問地址不會改變(還是第一個servlet的訪問地址),轉發地址對瀏覽器是隱藏的
重定向時,位址列的訪問地址會發生改變 (變成最後一個servlet的訪問地址 ),對瀏覽器可見
3) 因為請求轉發是同一次請求,所以可以利用 request 作用域進行存值,取值
但是重定向是兩次不同的請求,所以不能利用 request 作用域,但可以使用 session 作用域來存值,取值
4) 請求轉發的目標只能是本專案的 servlet / jsp
重定向的目標可以是 任意的,既可以是本專案中的 地址,也可以是第三方的地址
*****結論:
- 當要跳轉的兩個地址關係密切時,使用 請求轉發
- 當要跳轉的兩個地址關係不密切時,就使用 重定向