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... ...
一周排行
  • 【五分鐘的dotnet】是一個利用您的碎片化時間來學習和豐富.net知識的博文系列。如果您現在正在使用.NetCore的話,相信您對await 和 async這兩個關鍵字再熟悉不過了。它們是為非同步編程提供的語法糖,便於我們在代碼中更便捷的進行非同步操作。await 和 async其實是對Task對象都... ...
  • .NET基金會是一個獨立的非營利組織,於2014年成立,旨在圍繞 .NET 不斷增長的開源技術集合,促進開放開發和協作。它是商業和社區開發人員的論壇,通過促進開放性,社區參與和快速創新來增強.NET生態系統的未來。要使.NET 基金會真正獨立並由社區運營,則需要獨立資助。過去,.NET 基金會依靠來... ...
  • 微信公眾號: "Dotnet9" ,網站: "Dotnet9" ,問題或建議: "請網站留言" , 如果對您有所幫助: "歡迎贊賞" 。 .NET CORE(C ) WPF 方便的實現用戶控制項切換(祝大家新年快樂) 快到2020年了,祝大家新年快樂,今年2019最後一更,謝謝大家支持! 閱讀導航 1 ...
  • 內容有點多,請耐心! 最近公司的有這個業務需求,又很湊巧讓我來完成: 首先想要對接,先要一個公眾號,再就是開發文檔了:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html 不過請註意這一點 ok, ...
  • MyBatis MyBatis是Apache的一個開源項目iBatis, iBatis一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架。 iBatis 提供的持久層框架包括SQL Maps和Data Access Objects(DAO) Mybatis 是一個 ...
  • 前言 Stanley B.Lippman 先生所著的《C++ Primer》是學習C++的一本非常優秀的教科書,但《C++ Primer》作為一本大部頭書,顯然不適合所有的初學者。所以Lippman先生又返璞歸真地寫了這本短小輕薄的《Essentia C++》。這本書以簡短的章節篇幅,幫助初學者快速... ...
  • 大數據環境需要的安裝包合集,包括: apache flume 1.7.0 bin.tar.gz apache hive 1.2.1 bin.tar.gz hadoop 2.7.2.tar.gz hbase 1.3.1 bin.tar.gz jdk 8u144 linux x64.tar kafka_ ...
  • 在項目當中資料庫一般都會成為主要的性能與負載瓶頸,那麼針對資料庫各項性能指標的監控與對應的優化是開發與運維人員需要面對的主要工作,而且這部分的工作會貫穿項目從開發到運行的整個周期里。 這篇文章中我們對MySql資料庫中的幾個主要的性能指標的計算與統計進行下說明與總結。 在MySql中通過show g ...
  • 1. Cookie Cookie,有時也用其複數形式Cookies,指某些網站為了辨別用戶身份、進行session跟蹤而儲存在用戶本地終端上的數據(通常經過加密)。Cookie最早是網景公司的前雇員Lou Montulli在1993年3月的發明。Cookie是由伺服器端生成,發送給User-Agen ...
  • 1. PreparedStatement預編譯的語句對象 預編譯語句PreparedStatement 是java.sql中的一個介面,它是Statement的子介面。通過Statement對象執行SQL語句時,需要將SQL語句發送給DBMS,由 DBMS首先進行編譯後再執行。預編譯語句和State ...
x