狂神Java Web (六)Cookie & Session
阿新 • • 發佈:2021-07-28
Cookie & Session
會話:使用者開啟瀏覽器,點選很多連結,訪問多個web資源,關閉瀏覽器,該過程可以稱為會話。
有狀態會話:一個網站,怎麼證明你來過?
客戶端 服務端
- 服務端給客戶端一個信件,客戶端下次訪問服務端帶上信件就可以了; cookie
- 伺服器登記你來過了,下次來的時候匹配你; session
儲存會話的兩種技術 :
- cookie
- 客戶端技術(響應,請求)
- session
- 伺服器技術,可以儲存使用者的會話資訊。可以把資訊或資料放在Session中。
應用場景:自動登入
Cookie
- 從請求中拿到cookie資訊
- 伺服器響應給客戶端cookie
Cookie[] cookies = req.getCookies(); // 獲得Cookie
cookie.getName(); // 獲得Cookie中的鍵key
cookie.getValue(); // 獲得Cookie中的值value
new Cookie("lastLoginTime", System.currentTimeMillis() + ""); // 新建一個Cookie
cookie.setMaxAge(24 * 60 * 60); // 設定Cookie的有效期
resp.addCookie(cookie); // 響應給客戶端一個Cookie
Cookie:一般儲存在本地的使用者目錄下, appdata;
儲存上次登入時間的例子:
package com.maple.servlet; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; /** * 儲存使用者上一次訪問的時間 * * @author maple_w * Created on 21/07/28 028 19:59 */ public class CookieServlet01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); // Cookie, 伺服器端從客戶端獲取 Cookie[] cookies = req.getCookies(); // 判斷Cookie是否存在 if (cookies != null) { out.write("上次訪問的時間:"); for (Cookie cookie : cookies) { String name = cookie.getName(); String value = cookie.getValue(); if (name.equals("lastLoginTime")) { long l = Long.parseLong(value); Date date = new Date(l); out.write(date.toLocaleString()); } } } else { out.write("首次訪問"); } // 伺服器給客戶端響應一個cookie Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + ""); // 設定cookie有效期為1天 cookie.setMaxAge(24 * 60 * 60); resp.addCookie(cookie); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
一個網站的Cookie是否存在上限?
- 一個Cookie只能儲存一個資訊;
- 一個web站點可以給瀏覽器傳送多個cookie,最多存放20個;
- 300個Cookie,瀏覽器上限;
- Cookie大小有限制,4kb;
刪除Cookie:
- 不設定有效期,關閉瀏覽器,自動失效;
- 設定有效期為0;(手動刪除)
編碼解碼:
URLEncoder.encode("狂神", "utf-8")
URLDecoder.decode(cookie.getValue(), "utf-8"))
如果要讀取中文Cookie,後臺顯示中文正常也不行,如果要瀏覽器顯示正常,還需要新增:
// 新增這個才能有效讓頁面顯示中文不亂碼
resp.setContentType("text/html;charset=utf-8");
讀取中文的小例子:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
// 新增這個才能有效讓頁面顯示中文不亂碼
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
Cookie[] cookies = req.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
out.write(cookie.getName());
out.write(URLDecoder.decode(cookie.getValue(), "utf-8"));
System.out.println(cookie.getName());
System.out.println(URLDecoder.decode(cookie.getValue(), "utf-8"));
}
}
Cookie cookie = new Cookie("name", URLEncoder.encode("狂神", "utf-8"));
resp.addCookie(cookie);
}
Session (重點)
什麼是session:
- 伺服器會給每個使用者(瀏覽器)建立一個Session物件。
- 每個Session獨佔一個瀏覽器,只要瀏覽器沒有關閉,這個Session就存在。
- 使用者登入後,整個網站都可以訪問。--> 儲存使用者資訊、儲存購物車資訊等
Session和Cookie的區別:
- Cookie把使用者的資料寫給使用者的瀏覽器,瀏覽器儲存;(可以儲存多個)
- Session把使用者的資料寫到使用者獨佔的Session中,伺服器端儲存;(儲存重要資訊,減少伺服器資源的浪費)
- Session物件由伺服器建立,
使用場景:
- 儲存一個登入使用者的資訊;
- 購物車資訊;
- 在整個網站中經常會使用的資料,將其儲存在session中;
使用session:
往Session中寫資訊:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解決亂碼問題
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
// 得到Session
HttpSession session = req.getSession();
// 給Session中存東西
// session.setAttribute("name", "狂神");
session.setAttribute("name", new Person("狂神", 33));
// 獲取Session的ID
String id = session.getId();
// 判斷是否是新的Session
if (session.isNew()) {
resp.getWriter().write("session 建立成功, ID: " + id);
} else {
resp.getWriter().write("session 已經在伺服器中存在了, ID: " + id);
}
// 猜想Session做了什麼事情:
// Cookie cookie = new Cookie("JSESSIONID",id);
// resp.addCookie(cookie);
}
從Session中讀取資訊:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解決亂碼問題
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
// 得到Session
HttpSession session = req.getSession();
// String name = (String) session.getAttribute("name");
Person person = (Person) session.getAttribute("name");
System.out.println(person);
}
清除Session:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
// 手動登出session,但因為瀏覽器在訪問,會立即生成一個新的session
session.invalidate();
}
或是在web.xml
中設定預設失效時間:
<!-- 設定session預設失效時間 -->
<session-config>
<!-- 15分鐘後session自動失效,分鐘為單位 -->
<session-timeout>1</session-timeout>
</session-config>
ServletContext (ApplicationContext)是在Session之上更高階的一個概念,可以儲存多個不同使用者的共享資訊,如使用者統計等。