1.Cookie
package com.hxuner.web;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* 1.會話的概念:
* -------- 從用戶打開瀏覽器,對服務器進行多次請求,到關閉瀏覽器,稱爲一次會話--------------
* 用戶爲了實現一個目標,而對服務器進行一系列的訪問,稱爲一次會話
*
* 2.會話的挑戰
* http協議是一次請求一次應答後斷開連接,每次請求對於服務器來說都是一次新的請求
* 但是,在會話過程中,會產生一個臨時數據(會話狀態),比如用戶登錄的狀態,用戶添加的購物車等等
* 如何存儲這些數據,實現整個會話期間的數據共享,就是一個挑戰
*
* 會話技術就是會話的挑戰的解決方案
*
*/
/*
* Cookie
* 1.概念
* Cookie將用戶產生的會話數據保存在客戶端瀏覽器上,是瀏覽器解決方案
*
* 服務器收到請求->set-cookie應答頭->將數據返回給瀏覽器,瀏覽器收到cookie後,會存儲在瀏覽器的內存/硬盤上
* 瀏覽器再次發送請求時->將符合條件的Cookie以請求頭的形式->發送給服務器
* 因此服務器可以在收到請求後,拿到之前在瀏覽器保存的會話數據.
*
*
* 2.原生API
* response.setHeader("set-cookie","name=value") response設置cookie
* request.getHeader("cookie") request獲取cookie
*
*/
//瀏覽器輸入http://localhost/day012JavaWebCookie/servlet/Cookie01
public class Cookie01 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//處理亂碼
response.setContentType("text/html;charset=utf-8");
//1.接受用戶請求,獲取當前時間->本次訪問時間
String dateStr=new Date().toLocaleString();
//2.通過cookie將本次訪問時間返回給瀏覽器
//----------response.setHeader("set-cookie", "time="+dateStr);--------response設置cookie-----------------------------
response.setHeader("set-cookie", "time="+dateStr);
//response.addHeader("set-cookie", "age=18"); //添加數據要addHeader(),不然相同的key,值會覆蓋,只留一份
//3.獲取用戶傳來的Cookie中攜帶的上次訪問時間
//---------request.getHeader("cookie");----------------------request獲取cookie--------------------------
String lasttime=request.getHeader("cookie");
//4.給用戶應答,你上次訪問的時間是...
if(lasttime==null){
//是第一次訪問
response.getWriter().write("你是第一次訪問");
}else{
response.getWriter().write("你上次訪問時間"+lasttime.split("=")[1]); //lasttime="time=datestr" =分隔爲兩部分time=和datestr 取第二個
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package com.hxuner.web;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* sun公司提供操作cookie的API
* Cookie cookie=new Cookie(name,value); 創建cookie對象
* response.addCookie(cookie); cookie對象存入response
* Cookie[] cs=request.getCookies(); 獲取cookie對象
*
*
* 設置Cookie的有效時間
* cookie.setMaxAge(xxs);
* 如果不設定時間,Cookie默認是會話級別的,存儲在瀏覽器的內存中,瀏覽器關閉則Cookie被銷燬
* 如果設定了時間,Cookie會被持久化到硬盤上,不會隨瀏覽器的關閉而銷燬
*
* 設置Cookie的路徑
* cookie.setPath()
* 如果瀏覽器請求的domain+path與當前Cookie的domain+path一致,或者是其子路徑,則會自動攜帶當前Cookie
*
* 設置Cookie的域名
* cookie.setDomain
* 一般不使用,以免被瀏覽器拒絕
*
* 刪除Cookie
* Cookie cookie=new Cookie("time",""); //name相同
cookie.setPath(request.getContextPath()+"/"); //path相同,domain設置無用,被瀏覽器拒絕
cookie.setMaxAge(0); //同一個cookie,後發的cookie覆蓋之前的,存活時間0秒
response.addCookie(cookie);
如果想要刪除一個Cookie,向瀏覽器發送一個新的同name,同path,同domain的Cookie,只需要將Cookie的maxAge設置爲0
由於瀏覽器是根據 name+path+domain 來區分Cookie的, 所以當兩個cookie的上述條件相同時, 瀏覽器就會認爲是同一個Cookie,
那麼後發的Cookie會覆蓋之前的, 而後發的Cookie的存活時間爲0, 所以瀏覽器收到後也會立即刪除!!
注意:
1. Cookie中不能攜帶中文字符,需要使用URLEncoder.encode(str,charset),將中文字符轉成對應的charset的表示 (服務器端)
2. 在頁面上,爲了正常顯示Cookie中攜帶的中文,必須使用URLDecoder.decode(str,charset),將字符集的表示轉爲中文 (JSP)
3. 一個瀏覽器可以存儲多個站點發來的Cookie,一個站點也可以給多個瀏覽器發送Cookie
4. 一個瀏覽器最多存儲300個Cookie,每個站點20個,每個Cookie的大小上限是4kb
*/
//瀏覽器輸入http://localhost/day012JavaWebCookie/servlet/Cookie02
public class Cookie02 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//演示sun公司提供的API
//處理應答亂碼
response.setContentType("text/html;charset=utf-8");
//1.獲取當前時間
String dateStr=new Date().toLocaleString();
//2.通過cookie將本次訪問時間返回給瀏覽器
//Sun公司提供了Cookie類,代表了一個Cookie信息
Cookie cookie=new Cookie("time",dateStr); //創建Cookie對象 --------------new Cookie("time",dateStr);-----------------
//response.setHeader("set-cookie", "time="+dateStr);等價於2,3兩步
//-------------------------------cookie額外的設置start------------------------------------------------------------------------
/*
Cookie默認是會話級別的,也是存儲在瀏覽器的內存中,瀏覽器關閉cookie銷燬
如果希望瀏覽器關閉而Cookie依舊存在,需要給Cookie設定一個有效時間
對於設定了有效時間的Cookie,瀏覽器會將Cookie持久化到硬盤上存儲
*/
//設定時長30天,單位s
cookie.setMaxAge(60*60*24*30); //設置Cookie存活時間 -----------------cookie.setMaxAge()單位s----------------
/*
如果瀏覽器請求的domain+path與當前Cookie的domain+path一致,或者是其子路徑,則會自動攜帶當前Cookie,否則不攜帶cookie
默認情況下,cookie攜帶的path屬性是當前Servlet的父路徑,現在默認路徑是http://localhost/day012JavaWebCookie/Servlet
如果希望 訪問http://localhost/day012JavaWebCookie/ 攜帶數據,就要設置setPath()
*/
//request.getContextPath()方法返回"",則setPath不生效,需要加/
cookie.setPath(request.getContextPath()+"/"); //設置Cookie路徑 ----------------setPath(String path);-----------------
//--------瀏覽器標記一個cookie,通過name,path,domain組合來唯一標識同一個cookie------------
//設置域名的api,不建議設定->有可能被瀏覽器拒絕,小網站可以仿造其他域名,瀏覽器認爲不安全
//cookie.setDomain(pattern); //設置域名的api--------------cookie.setDomain(pattern); -----------
//-------------------------------cookie額外的設置end-----------------------------------------------------------------------------
//3.將Cookie存入response
response.addCookie(cookie); //將Cookie對象存入response----------response.addCookie(cookie);----------------
//4.獲取用戶隨請求傳來的Cookie
//request.getCookies()返回用戶傳來的所有cookie
Cookie[] cs=request.getCookies(); //獲取所有cookie --------Cookie[] cs=request.getCookies();----------------------
Cookie findC=null;
if(cs!=null){
for(Cookie c:cs){
if("time".equals(c.getName())){ //獲取cookie的名字 ----------Cookie.getName()---------------------
findC=c;
break;
}
}
}
if(findC!=null){
response.getWriter().write("你上次訪問的時間是"+findC.getValue()); //獲取cookie的值 --------Cookie.getValue()----------
}else{
response.getWriter().write("你是第一次訪問");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package com.hxuner.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Cookie03 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//sun公司沒有提供直接刪除Cookie的API
//刪除Cookie
//如果想要刪除一個Cookie,向瀏覽器發送一個新的同name,同path,同domain的Cookie,只需要將Cookie的maxAge設置爲0
//由於瀏覽器是根據 name+path+domain 來區分Cookie的, 所以當兩個cookie的上述條件相同時, 瀏覽器就會認爲是同一個Cookie,
//那麼後發的Cookie會覆蓋之前的, 而後發的Cookie的存活時間爲0, 所以瀏覽器收到後也會立即刪除!!
Cookie cookie=new Cookie("time",""); //name相同
cookie.setPath(request.getContextPath()+"/"); //path相同,domain設置無用,被瀏覽器拒絕
cookie.setMaxAge(0); //後發的cookie覆蓋之前的,存活時間0秒
response.addCookie(cookie);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
2.Session
package com.hxuner.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* Session
* 概念:Session是將用戶產生的會話信息存儲在服務器端,是服務器端的解決方案
* Session是四大作用域之一,稱爲session作用域
*
* 生命週期:
* 創建:用戶第一次調用request.getSession()方法,會爲當前用戶創建一個Session對象
* 存活:默認在內存中存在30分鐘,--------是從最後一次訪問session開始算-------------
* 銷燬:1.默認情況 超過30分鐘沒有訪問該session,則銷燬
*
* 2.自殺 session.invalidate()->馬上銷燬該session對象
*
* 3.意外銷燬 服務器異常關閉,所有的session會隨應用的銷燬而銷燬
*
* 4.鈍化和活化 服務器正常關閉時,所有未超時的session會被序列化到tomcat/work/catalina/虛擬主機/web應用/SESSIONS.ser來保存,稱爲鈍化
* 當服務器啓動時,所有鈍化的session會被反序列化到內存中,繼續生效,稱爲活化
*
* API:
* 和其他作用域一致
*/
public class Session01 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--
禁用Cookie的情況下使用Session
URL重寫: 就是在傳入的URL地址後拼接JSESSIOINID返回一個新的地址, 用來在禁用Cookie的情況下用url地址來攜帶JSESSIOINID
response.encodeURL(String url);
//--如果是普通的地址用這個方法
response.encodeRedirectURL(String url);
//--如果地址是用來進行重定向的,用這個方法
-->
<a href="<%=response.encodeUrl("/day12/BuyServlet?prod=阿迪王皮鞋") %>">阿迪王皮鞋</a><br>
<a href="/day12/BuyServlet?prod=藍月河洗衣液">藍月河洗衣液</a><br>
<a href="/day12/BuyServlet?prod=TLC電視">TLC電視</a><br>
<a href="<%=response.encodeUrl("/day12/PayServlet") %>">支付</a><br>
</body>
</html>
package com.hxuner.web;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
public class pbuyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.處理亂碼
response.setContentType("text/html;charset=utf-8");
//2.獲取請求參數
String prod=request.getParameter("prod");
if(prod!=null){
//手動編解碼解決get請求亂碼
prod=new String(prod.getBytes("iso8859-1"),"utf-8");
}
//3.將商品信息添加到session作用域
//第一次調用該方法時,會爲用戶創建一個新的Session對象
//後面用戶多次調用該方法,該方法返回的是第一個創建的那個session對象
HttpSession session=request.getSession();
/*
怎麼解決瀏覽器關閉之後, 無法使用瀏覽器關閉之前的Session??
(注意: 在訪問一個jsp時, 默認一上來就會創建session!!)
session還在,默認存在30分鐘,就是cookie銷燬,而cookie的session id唯一標識session也不能標識了
方案:讓cookie活久一點
*/
// 服務器依靠用戶攜帶的JSESSIONID的Cookie來查找對應的session對象,該cookie默認是會話級別,瀏覽器關閉則銷燬
// 沒有API可以直接訪問到該Cookie對象,因此可以自己重新發送一個同名的Cookie
Cookie cookie=new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(60*30);//30分鐘
cookie.setPath(request.getContextPath()+"/");
response.addCookie(cookie);
session.setAttribute("prod", prod);
//4.給用戶請求
response.getWriter().write("恭喜您,"+prod+"已經成功添加到購物車");
response.setHeader("refresh", "3;url="+response.encodeRedirectUrl(request.getContextPath()+"/sales.jsp"));
/*
禁用Cookie的情況下使用Session
URL重寫: 就是在傳入的URL地址後拼接JSESSIOINID返回一個新的地址, 用來在禁用Cookie的情況下用url地址來攜帶JSESSIOINID
response.encodeURL(String url);
//--如果是普通的地址用這個方法
response.encodeRedirectURL(String url);
//--如果地址是用來進行重定向的,用這個方法
*/
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package com.hxuner.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class payServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
// 從用戶綁定的session作用域中獲取到已添加的商品
// req.getSession(false)->嘗試獲取(而不是創建)該用戶綁定的session,如果該session不存在,則返回null
HttpSession session=request.getSession(false);
//要麼無session要麼session無prod商品
if(session==null||session.getAttribute("prod")==null){
response.getWriter().write("你還沒有購買商品,3秒後跳轉購買商品頁面");
response.setHeader("refresh", "3;url="+request.getContextPath()+"/sale.jsp");
}else{
response.getWriter().write("你購買的商品是"+session.getAttribute("prod")+",支付¥100");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package com.hxuner.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* Cookie和Session的區別
* -------------------------------------------------------------
* 將會話數據存入瀏覽器端,是瀏覽器端的解決方案
* 優勢:不佔用服務器的內存空間
* Cookie: 存放的時間比較長
*
* 劣勢:可能因爲用戶的誤操作而被刪除
* 用戶機的防火牆級別較低,Cookie中的數據可能被盜取
*
* 需要存放較長時間,且安全性不太高的數據
*
* --------------------------------------------------------------------
*
* 將會話數據存在服務器端,是服務器端解決方案
* 優勢:存在服務器的內存中,服務器防火牆級別高,所以安全性高
* Session: 被誤操作刪除的可能性非常低
*
* 劣勢:存在時間比較短,因爲會佔用服務器的內存
*
* 安全性比較高的,不需要長期存放的數據,使用Session
*
*
* ----------------------------------------------------------------
* 注意:又想長時間保存數據,安全性又高,可以使用數據庫
*/
public class zCookie_Session extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}