javaWeb核心技術第八篇之Cookie和Session

来源:https://www.cnblogs.com/haizai/archive/2019/08/24/11406171.html

會話技術: 會話是什麼? 瀏覽器和伺服器交互,瀏覽器打開網頁訪問伺服器,會話開始,正常交互. 瀏覽器關閉,會話結束. 會話能幹什麼? 會話可以共用數據. Cookie和session將數據保存在不同的位置 進行數據共用 Cookie入門案例 1.創建一個cookie對象 a. Cookie cook ...


會話技術:
會話是什麼?
瀏覽器和伺服器交互,瀏覽器打開網頁訪問伺服器,會話開始,正常交互.
瀏覽器關閉,會話結束.
會話能幹什麼?
會話可以共用數據.
Cookie和session將數據保存在不同的位置 進行數據共用

Cookie入門案例

1.創建一個cookie對象
a. Cookie cookie = new Cookie(String name,String value);
2.響應給瀏覽器
a.Response.addCookie(cookie)
3.再次請求時需要獲得cookie
a.Request.getCookies() 獲得的是數組(包含所有的cookie,如果沒有cookie,返回值為null)
4.Cookie.getName() 獲得名稱 cookie.getValue() 獲得值

Cookie原理--會話級別cookie
Http中頭信息進行數據傳輸
Cookie預設是會話級別的cookie,瀏覽器打開訪問伺服器 ,交互的時候數據共用,當前瀏覽器關閉的時候數據失效.

Cookie細節--持久化級別的cookie

以後開發需要設置時間(cookie的存活時間)
Cookie.setMaxAge(秒)
以後開發需要設置路徑(訪問路徑)(作用:cookie 作用域 如果請求地址欄跟cookie文件里cookie路徑一致 自動攜帶)
Cookie.setPath("/") (作用:表示該伺服器下所有的項目允許共用cookie)

6)如果不設置cookie的有效存活時間,預設cookie只在記憶體中有效,當程式結束後,記憶體中的cookie銷毀,不會寫入瀏覽器的緩存中,因此,
需要為cookie設置一個有效的時間,當程式運行完畢後,會將該cookie寫入瀏覽器的緩存中,即硬碟中保留。如果cookie的存活時間為0,
就相當於瀏覽器將刪除cookie刪除或無效.
7)在預設情況下,day08web應用的cookie只能被day08web應用的動態資源訪問,如果要讓其它的web資源訪問,得設置cookie.setPath("/day08-2"),預設cookie的path為當前web應用。
8)cookie是以文本文件的方式存於瀏覽器緩存中,而且裡面的內容明碼.

cookie細節:(面試)
1.cookie的value不可以為中文(因為在響應頭,響應頭在數據傳輸時,使用是http協議,而協議使用的是iso-8859-1 不支持中文)
2.cookie的設置 遵循4 2 3規則.
2.1:4 表示4kb :設置value的是長度是有限的(精準)
2.2:2 表示20個 : 表示一個網站(站點)最多支持20個cookie(不精準)
2.3:3 表示300個 : 一個瀏覽器最大存放cookie是300個(不精準)

案例:記錄本次登錄時間,顯示上次訪問時間

//編碼
response.setHeader("content-type","text/html;charset=utf-8");

//2.第二次訪問
//2.1獲得請求中攜帶的cookie數據
Cookie[] cookies = request.getCookies();
//2.2判斷數據是否為空
if(cookies != null) {
for(Cookie cookie : cookies) {
//判斷是最後一次訪問的cookie
if("lasttime".equals(cookie.getName())) {
response.getWriter().print("您上次訪問時間是" + cookie.getValue());
//重新賦值
//1.第一次訪問
//1.1創建一個cookie
Cookie cookie1 = new Cookie("lasttime",new Date().toLocaleString());

//1.1.1 設置最大存活時間
cookie1.setMaxAge(60*60);
//1.1.2設置路徑
cookie1.setPath("/");

//1.2將cookie響應給瀏覽器
response.addCookie(cookie1);
}
}
}else {
//1.3列印第一訪問
response.getWriter().print("您是第一次訪問伺服器");
//1.第一次訪問
//1.1創建一個cookie
Cookie cookie = new Cookie("lasttime",new Date().toLocalString());

//1.1.1設置最大存活時間
cookie.setMaxAge(60*60);
//1.1.2設置路徑
cookie.setPath("/");

//1.2將cookie響應給瀏覽器
response.addCookie(cookie);
}

Session的底層基於cookie,cookie只用於保存id,伺服器根據id去找session對象
過程:
1.伺服器第一次調用getSession()將創建一個Session對象,並且會給這個session對象賦值唯一的id屬性sessionld = 1234.
2.session的底層創建一個cookie對象,目的sessionid傳給瀏覽器 new Cookie(jsessionid,1234),瀏覽器端會自動保存jsessionid
3.下一次再次請求時,自動攜帶jsession=1234,伺服器第二次調用getSession()根據session獲得唯一的session對象.
總結:session的底層基於cookie

Session生命周期:

問題:如果瀏覽器端禁用cookie session能否使用?
session生命周期
session的底層基於cookie,使用的是會話級的cookie,瀏覽器關閉cookie,但session還是存在伺服器,只是因為cookie丟了,所以session找不回來了.

創建:
1.第一次調用request.getSerssion()時創建.
銷毀:
2.1:超時30分鐘自動銷毀,tomcat配置可以修改(路徑在:tomcat -- conf -- web.xml)
例如:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
2.2 手動調用 session.invalidate()銷毀.或者setMaxInactiveInterval(int interval)(不常用)
2.3 伺服器非正常關閉.
開啟伺服器後,點擊了Console的紅色按鈕.

session如何持久化?
將sessionid保存到資料庫或者可以在瀏覽器端將cookie持久化.

作用域對象總結:

數據共用:Servlet中的域對象.
類型ServletRequest HttpSession ServletContext
對象request session ServletContext

api:
setAttribute(String name,Object value) :
getAttribute(String name) 返回值Ojbect :
removeAttribute() :

域對象:在一定範圍內共用數據.
request:一個請求內多個資源可以共用數據(使用的技術 請求轉發)
session:一個會話內共用數據,可以有多個請求.
servletContext : 一個項目內多個會話,多個請求共用同一份數據(全局變數時使用)

以後作用域如何選擇?
1.能小不大原則.
2.需求優先原則.

Cookie也可以進行數據共用,但不是域對象,因為指的是伺服器端技術.
Cookie和Session關係?如何選擇?
Session的底層基於cookie.
如何選擇?主要看數據的重要程度.

如果想使用Servlet必須要有tomcat , web中一共13套規範(介面) tomcat支持servlet和jsp

一次性驗證碼

@WebServlet(urlPatterns={"/BDVerifyCodeServlet"})//等效web.xml配置
public class BDVerifyCodeServlet extends HttpServlet{

// 圖片高度
private static final int IMG_HEIGHT = 100;
// 圖片寬度
private static final int IMG_WIDTH = 30;
// 驗證碼長度
private static final int CODE_LEN = 4;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 用於繪製圖片,設置圖片的長寬和圖片類型(RGB)
BufferedImage bi = new BufferedImage(IMG_HEIGHT, IMG_WIDTH, BufferedImage.TYPE_INT_RGB);
// 獲取繪圖工具
Graphics graphics = bi.getGraphics();
graphics.setColor(new Color(100, 230, 200)); // 使用RGB設置背景顏色
graphics.fillRect(0, 0, 100, 30); // 填充矩形區域

// 驗證碼中所使用到的字元
char[] codeChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456".toCharArray();
String captcha = ""; // 存放生成的驗證碼
Random random = new Random();


graphics.setFont(new Font("楷體", Font.BOLD, 20));
for(int i = 0; i < CODE_LEN; i++) { // 迴圈將每個驗證碼字元繪製到圖片上
int index = random.nextInt(codeChar.length);
// 隨機生成驗證碼顏色
graphics.setColor(new Color(random.nextInt(150), random.nextInt(200), random.nextInt(255)));
// 將一個字元繪製到圖片上,並制定位置(設置x,y坐標)
graphics.drawString(codeChar[index] + "", (i * 20) + 15, 20);
captcha += codeChar[index];
}
// 將生成的驗證碼code放入sessoin中
req.getSession().setAttribute("code", captcha);
// 通過ImageIO將圖片輸出
ImageIO.write(bi, "JPG", resp.getOutputStream());
}
}

//效驗
try{
//編碼--
request.setCharacterEncoding("utf-8");
response.setHeader("content-type","text/html;charset=utf-8");

//1.獲得
//1.1用戶輸入的驗證碼 -- 表單的組件需要有name屬性
String verifyCode = request.getParameter("verifyCode");
//1.2獲得圖片生成的驗證碼
Object code = request.getSession().getAttribute("code");
//1.3情況session中驗證碼
request.getSession().removeAttribute("code");
if(code == null) {
//3.1存放錯誤記錄
request.setAttribute("msg","驗證碼失效");
//3.2請求轉發給當前頁面form.html
request.getRequestDispatcher("/form.jsp").forward(request,response);
return ;//等效else
}

//2.處理 //equalsIgnoreCase 不區分大小寫
if(verifyCode.equalsIgnoreCase(code.toString())) {
//3.響應成功
response.getWriter.prinltn("success");
}else {
//3.失敗 請求轉發
//3.1存放錯誤記錄
request.setAttribute("msg","驗證碼錯誤");
//3.2請求轉發給當前頁面form.jsp
request.getRequestDispatcher("/form.jsp").forward(request,response);//刷新頁面

}

}catch(Exception e) {

}


debug : 裡面在Progress視窗下報building和sleeping,那就是編譯不過去了.
如果能編譯過去,在Project視窗下點擊Clean(可以重新編譯一個,或者多個),出現Building workspace有綠色條,說明沒問題,如果沒有
那就是Eclipse掛掉了.解決的辦法就是重新啟動.

案例:
public class Parent {
public void demo1() {
System.out.println("1");
this.demo2();
//在編譯時,this的確表示parent
//但在運行時,表示是son
}
//不可以刪,如果刪了,編譯不過去
public void demo2() {
System.out.println("2");
}
}

public class Son extends Parent {
public void demo1() {
super.demo1();
System.out.println("3");
this.demo2();
}

public void demo2() {
System.out.println("4");
}
public static void main(String[] args) {
Son son = new Son();//new 是誰 this代表誰.
son.demo1();
}

答案:1434
}

更改項目的jdk版本:項目右鍵 -- Project Facets -- java -- 1.7(改這裡) 和 Java Compiler -- JDK -- 1.7(改這裡)

JS : 函數問題
//1.函數的聲明問題 跟參數沒有關係 只要函數名稱一樣 產生覆蓋的效果
//2.函數的調用問題 跟參數沒有關係
//3.函數當中有arguments 用來接收所有的數據

function demo2() {
alert(1);
}
function demo2() {
alert(arguments.length);//arguments 表示一個數組,用數組來接收傳過來的所有參數值
//arguments.length : 獲取的是這個數組的長度
alert(a);

}
demo2("1","2","3");

//$(對象).css("參數") ; 獲得 (底層是這麼判斷的,如果arguments是1表示就一個參數,這樣就是表示獲得,如果不止一個參數,那就是設置)
//$(對象).css("參數","參數"); 設置

js中遍歷;
var arr = new Array("三金","三金","絲巾");
//普通遍歷
for(var i = 0;i < arr.length ; i++) {
alert(arr[i]);
}
//增強遍歷(forin) foreach(Object obj : 數組) :(var相當於Object;variables相當於索引(或者說是key或者是下標); :相當於in ; 數組相當於arr)
for(var variables in arr) {
alert(arr[variables]);
}
arr["abc"] = "1234";//數組可以使用字元串當下標(數組的屬性)
alert(arr["abc"]);
</srcipt>
</head>
<body>
<input id="usernameId" type="text" name="username" value="二斤rose" />

<script>
var userNameObj = document.getElementById("usernameId");
//增強for 可以遍歷對象的屬性
//現在的userNameObj相當於是一個數組
for(var temp in userNameObj) {
alert(temp);//temp表示屬性的key值(例如:type,name,value等等很多)
if(temp == "value") {
//數組名[temp]
alert(userNameObj[temp]);
}
}
</script>
</body>


您的分享是我們最大的動力!

更多相關文章
  • 摘要: 玩轉ES6解構賦值。 原文: "5個 JS 解構有趣的用途" 譯者:前端小智 1. 交換變數 通常交換兩個變數的方法需要一個額外的臨時變數,來看看例子: 是一個臨時變數,它先保存 的值。然後把 的值賦值給 ,接著將 值賦給 。 如果使用解構的方式會更簡單,不需要什麼鬼的 變數。 是解構賦值, ...
  • 是否有一些函數可以告訴我字元串在記憶體中占用多少位元組? 我需要設置套接字緩衝區的大小,以便一次傳輸整個字元串。 解決方案 但實際上你需要知道它代表的長度,所以類似的東西len(s)應該足夠了。 本文首發於Python黑洞網,博客園同步更新 ...
  • 在項目開發中,日誌系統是必不可少的,用`AOP`在Web的請求做入參和出參的參數列印,同時對異常進行日誌列印,避免重覆的手寫日誌,完整案例見文末源碼。 ...
  • 本文主要以一些簡單的小例子,簡述在SpringMVC開發過程中,經常用到的Request方面的內容,僅供學習分享使用,如有不足之處,還請指正。 ...
  • - False bool 類型的假值。 給 False 賦值是非法的並會引發 SyntaxError。 - True bool 類型的真值。 給 True 賦值是非法的並會引發 SyntaxError。 - None NoneType 類型的唯一值。 我理解為空值。 - NotImplemented ...
  • Tinymce富文本 前臺和後臺的使用 一,後臺 Admin 1. 於 settings.py 文件中修改 INSTALLED_APPS 2. 於 settings.py 文件中增添如下配置 1 # 富文本配置 2 TINYMCE_DEFAULT_CONFIG = { 3 'theme': 'adv ...
  • 修改列表中的元素: output: ['history','Chinese','English'] 列表中添加元素: 在末尾添加: output:['math','English'] ['math','English','Chinese'] 插入元素: output:['math','English ...
  • 在 IntelliJ IDEA 中,沒有類似於 Eclipse 工作空間(Workspace)的概念,而是提出了Project和Module這兩個概念。多module有一個父maven工程,多個子工程。在多個子工程中,可能有一個web工程,也可能有多個web工程。這樣的好處在於大大解耦各個modul... ...
一周排行
  • 比如要拆分“呵呵呵90909086676喝喝999”,下麵當type=0返回的是中文字元串“呵呵呵,喝喝”,type=1返回的是數字字元串“90909086676,999”, private string GetStrings(string str,int type=0) { IList<strin ...
  • Swagger一個優秀的Api介面文檔生成工具。Swagger可以可以動態生成Api介面文檔,有效的降低前後端人員關於Api介面的溝通成本,促進項目高效開發。 1、使用NuGet安裝最新的包:Swashbuckle.AspNetCore。 2、編輯項目文件(NetCoreTemplate.Web.c ...
  • 2020 年 7 月 30 日, 由.NET基金會和微軟 將舉辦一個線上和為期一天的活動,包括 微軟 .NET 團隊的演講者以及社區的演講者。本次線上大會 專註.NET框架構建微服務,演講者分享構建和部署雲原生應用程式的最佳實踐、模式、提示和技巧。有關更多信息和隨時瞭解情況:https://focu... ...
  • #abp框架Excel導出——基於vue #1.技術棧 ##1.1 前端採用vue,官方提供 UI套件用的是iview ##1.2 後臺是abp——aspnetboilerplate 即abp v1,https://github.com/aspnetboilerplate/aspnetboilerp ...
  • 前言 本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。 作者:碧茂大數據 PS:如有需要Python學習資料的小伙伴可以加下方的群去找免費管理員領取 input()輸入 Python提供了 input() 內置函數從標準輸入讀入一 ...
  • 從12年到20年,python以肉眼可見的趨勢超過了java,成為了當今It界人人皆知的編程語言。 python為什麼這麼火? 網路編程語言搜索指數 適合初學者 Python具有語法簡單、語句清晰的特點,這就讓初學者在學習階段可以把精力集中在編程對象和思維方法上。 大佬都在用 Google,YouT ...
  • 在社會上存在一種普遍的對培訓機構的學生一種歧視的現象,具體表現在,比如:當你去公司面試的時候,一旦你說了你是培訓機構出來的,那麼基本上你就涼了,那麼你瞞著不說,然後又通過了面試成功入職,但是以後一旦在公司被髮現有培訓經歷,可能會面臨被降薪,甚至被辭退,培訓機構出來的學生,在用人單位眼裡就是能力低下的 ...
  • from typing import List# 這道題看了大佬寫的代碼,經過自己的理解寫出來了。# 從最外圍的四周找有沒有為O的,如果有的話就進入深搜函數,然後深搜遍歷# 判斷上下左右的位置是否為Oclass Solution: def solve(self, board: List[List[s ...
  • import requests; import re; import os; # 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, li ...
  • import requests; import re; import os; import parsel; 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537. ...