Servlet進階教程(你不得不知道的Servlet知識點)

“ 人生的遊戲不在於拿了一副好牌,而在於怎樣去打好壞牌,世上沒有常勝將軍,勇於超越自我者才能得到最後的獎盃。”
你好,我是夢陽辰!快和我一起學習吧!

精彩回放:

Servlet入門詳細教程(你不得不知道的Servlet知識點)

01.適配器模式

1.適配器模式(Adapter Pattern)是作爲兩個不兼容的接口之間的橋樑。這種類型的設計模式屬於結構型模式,它結合了兩個獨立接口的功能。

**2.意圖:**將一個類的接口轉換成客戶希望的另外一個接口。適配器模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。

**3.主要解決:**主要解決在軟件系統中,常常要將一些"現存的對象"放到新的環境中,而新環境要求的接口是現對象不能滿足的。

我們可以在適配器中提供大量的方法,子類繼承後,可以在之類中直接使用。

4.例如:
1、系統需要使用現有的類,而此類的接口不符合系統的需要。

2、想要建立一個可以重複使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作,這些源類不一定有一致的接口。

3、通過接口轉換,將一個類插入另一個類系中。(比如老虎和飛禽,現在多了一個飛虎,在不增加實體的需求下,增加一個適配器,在裏面包容一個虎對象,實現飛的接口。)

當然我們也可以讓適配器實現接口,然後將部分需要的方法改爲抽象方法。子類繼承後,只需要實現抽象方法。是代碼不會出現冗餘

使用適配器的優點:
1、可以讓任何兩個沒有關聯的類一起運行。

2、提高了類的複用。

3、增加了類的透明度。

4、靈活性好。

缺點:
1、過多地使用適配器,會讓系統非常零亂,不易整體進行把握。

比如,明明看到調用的是 A 接口,其實內部被適配成了 B 接口的實現,一個系統如果太多出現這種情況,無異於一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構。

2.由於 JAVA 至多繼承一個類,所以至多隻能適配一個適配者類,而且目標類必須是抽象類。

例如:如果當前程序中A,B,C類只需要使用CommonIn接口中的m1,m2,m3方法。讓這些類直接事先這個接口,需要實現更多的方法。當只要使用其中部分方法時,這樣做,代碼冗餘。

解決方案:
1.寫一個類F,實現這個接口。(類F即爲適配器)
並將部分需要用的方法,用abstract修飾。(即抽象方法)。

2.A,B,C類繼承F類即可。

設計模式的分類:
創建型:解決對象的創建問題。

行爲型:該模式與方法,行爲,算法有關的設計模式。

結構型:更多類,更多對象組合成更大的結構解決某個特定的問題。

常見的設計模式:

Gof95:(1995年,四人組提出的23種設計模式)

  • 單例模式
  • 工廠模式
  • 適配器模式
  • 迭代模式【集合】
  • 策略模式【集合】
  • 裝飾器模式【IO流】

瞭解更多

JavaEE模式

**【問題描述】**我們之前所有的Servlet類直接實現了javax.servlet。Servlet接口。但是這個接口有很多方法是目前不需要的,我們可能只需要編寫service方法。直接實現Servlet接口代碼,使得代碼冗餘,有必要在中間添加一個適配器。以後所有的Servlet類不再直接實現Servlet接口,應該去繼承適配器類。

若在初始化的時候需要執行一段特殊的程序,建議重寫參數的init方法。
在這裏插入圖片描述
在這裏插入圖片描述

02.GET和POST

1.HTTP協議的詳細內容。

1.1什麼是HTTP協議?
超文本傳輸協議。
瀏覽器和服務器之間的一種通訊協議。

該協議是W3C負責指定的,其實本質上就是數據傳送格式提前制定好了。瀏覽器和服務器都必須按照這種數據格式進行接收和發送。

1.2HTTP協議包括幾部分?
請求協議:從Browser發送到Server的時候採用的數據傳送格式。

響應協議:從Server發送到Browser的時候採用的數據傳送格式。

1.3請求協議
請求協議包括四部分

請求行
消息報頭
空白行
請求體

請求行包括:請求方式 ,URI ,協議版本號
空白行:專門用來分離消息報頭和請求體的。

1.4響應協議
響應協議包括四部分:
狀態行
響應報頭
空白行
響應體

狀態行:協議版本號、狀態碼、狀態描述信息(狀態碼:200響應正常結束,404資源爲找到,500服務器內部錯誤…)

空白行:分離響應報頭和響應體
2.GET請求和POST請求的區別。

2.1 什麼情況下瀏覽器發送的請求是GET請求。什麼情況下瀏覽器發送的去請求是POST請求。

只有當使用表單from,並且將from標籤的method屬性設置爲method="post"纔是POST請求,其餘剩下所有請求方式都是基於GET請求方式。

2.2 GET請求在請求行上提交數據,格式:uri?name=value&name=value
這種提交方式最終提交的數據會顯示到瀏覽器的地址欄上。

2.3 POST請求在請求其中提交數據,相對安全,提交格式:name=value&name=value…
這種提交方式最終不會再瀏覽器地址欄上顯示。

2.4 POST請求再請求體中提交數據,所以POST請求提交數據沒有長度的限制【POST可以提交大數據】

2.5 GET請求在請求行上提交數據,所以GET請求提交的數據長度有限制。

2.6 GET請求只能提交字符串數據,POST請求可以提交任何類型的數據,包括視頻…,所以文件上傳必須使用POST請求提交。

2.7 GET請求最終的結果,會被瀏覽器緩存收納。

3 POST請求和GET請求該如何選者?
有敏感數據,必須使用POST
傳送數據不是普通字符串,必須使用POST
傳送的數據非常多,使用POST
這個請求是爲了修改服務器端資源,使用POST

GET請求多數情況下是從服務器讀取資源,這個讀取的資源在短時間之內是不會發生變化的,所以GET請求最終的結果瀏覽器緩存起來了。

POST請求是爲了修改服務器端的資源,而每一次修改的結果都是不同的,最終結果沒有必要被瀏覽器緩存。

數據和請求以問號隔開,數據之間以&符號連接。

4.安裝httpwatch工具,進行HTTP協議的監測。

5.緩存的解決方案

瀏覽器將資源緩存之後,緩存的資源是和某個特定的路徑綁定在一起的,只要瀏覽器再發送這個相同的請求路徑,這個時候回去緩存中獲取資源,不再訪問服務器,以這種方式降低服務器的壓力,提高用戶的體驗。但是有的時候,我們不希望走緩存,希望每一次都訪問服務器,可以在請求路徑後面添加時間戳。

例如:

http://ip:port/xxx/xxx?timestamp=23423424

JS怎麼獲取毫秒: new Date().getTime();

保證前端請求方式和後端程序處理方式一致

1.前端的頁面發送的請求方式應當和惡服務器端需要的請求方式一致。
服務器需要前端發送POST請求,那前端就應該發送POST請求,若發送GET請求,服務器端應當提示錯誤信息。

服務器需要前端發送GET請求,那前端就應該發送GET請求,若發送POST請求,服務器應當提示錯誤信息。

如何完成以上的請求?
在javaweb程序中想辦法獲取該請求是什麼類型的請求,POST?還是GET?

當我們獲取到請求方式之後,在javaweb程序中可以使用java語言中if語句進行判斷。
if(“POST”.equals(method)){
}else if(“GET”.equals(method)){
}

如何獲取請求方式呢?
HTTP的請求協議全部信息被全部封裝到javax.servlet.http.HttpServletRequest對象中。

在HttpServletRequest接口類型中有一個方法叫做:String getMethod();可以獲取請求方式。

public interface javax.servlet.http.HttpServletRequest extends ServletRequest{

}

代碼示例:

public class LoginServlet extends GenericServlet {

	@Override
	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
		//將ServletRequest,ServletResponse強制類型轉換成帶有Http的接口類型
		HttpServletRequest request1 =(HttpServletRequest)request;
		HttpServletResponse response1 =(HttpServletResponse)response;
		response1.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response1.getWriter();
		
		//獲取瀏覽器的請求方式
		String method=request1.getMethod();
		//LoginServlet是處理登錄的,要求必鬚髮送POST請求
		if("GET".equals(method)){
			//後臺報出錯誤,前臺報出錯誤
			
			out.print("你應該發送POST請求!");
			throw new RuntimeException("405-你應該發送POST請求");
		}
		if("POST".equals(method)) {
			out.print("正在登錄!");
		}
		//若程序執行到這裏說明用戶發送的是PUT請求,程序應該正常執行
		out.print("當前使用的是"+method+"請求!");
	}

}

HttpServlet原理

以上代碼每一個Servlet類都需要編寫,怎樣才能封裝一下,以後在每一個具體的servlet類中,不寫這樣的代碼了。
自己封裝:
在這裏插入圖片描述
在這裏插入圖片描述
這個HttpServlet類,sun公司替我們寫好了,直接繼承就好了。

總結servlet編程(重點)
1.剛開始我們需要實現servlet接口。

2.後面我們開始使用適配器Adapter(GenericServlet,自定義的父類。)

3.現在我們使用開始繼承HttpServlet類。重寫什麼方法取決於你的請求方式。

因此我們編寫一個類應當繼承HttpServlet,get請求重謝doGet方法,post請求重謝doPost方法。

doPost/doGet方法可以等同看做main方法。

405狀態表示前後臺請求方式不同。

比如我們用POST請求方式。
在這裏插入圖片描述
模板方法設計模式
Servlet規範中的:HttpServlet

HttpServlet是一個典型的模板方法設計模式。

其中的service(HttpServletRequest,HttpServletResponsee方法是典型的模板方法。

該方法定義了核心算法骨架,doGet,DoPost…具體的實現延遲到子類中完成。

模板類一般是抽象類。

模板方法設計模式可以做到,在不改變算法的前提下,可以重新定義算法步驟的具體實現。
在這裏插入圖片描述
模板方法設計模式的主要作用:
1.核心算法得到保護。

2.核心算法得到複用。

3.在不改變算法的前提之下,卻可以重新定義算法步驟的具體實現。
在這裏插入圖片描述

03.HttpServletRequest接口

1.繼承關係:
pulbic interface HttpServletRequest extends ServletRequest{
}

2.HttpServletRequest接口的實現類是WEB容器負責實現的。Tomcat服務器有自己的實現。程序員只需要面向接口調用方法。

3.HttpServletRequest這個對象封裝了哪些信息呢?
封裝了HTTP請求協議的全部內容。
如:
請求方式
URI
協議版本號
表單提交的數據

4.HttpServletRequest一般變量的名字叫做:request,表示請求。
HttpServletRequest對象代表一次請求。一次請求對應一個request對象。所以request對象的生命週期是短暫的。

5.什麼是一次請求。
網頁上點擊超鏈接,到最終網頁停下來。如輸入地址訪問。

6.HttpServletRequest接口常用的方法
表單提交的數據,會自動被封裝到request對象中,request對象中有Map集合存儲這些數據,Map集合的key是name,value是一個字符串類型的一維數組。

//1.通過key獲取value這個一維數組的元素(通常一維數組只有一個元素,所以這個方法用得較多
String getParameter(String name)  
//2.獲取整個Map對象
Map<String,String[]> getParameterMap()  
//3.獲取整個Map集合中的所有key
Enumeration<String> getParameterNames()  
//4.通過Map集合key獲取value.
String[] getParameterValues(String name)  

在這裏插入圖片描述
在這裏插入圖片描述

public class SaveUserServlet extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//獲取用戶信息,表單提交的這些數據被自動封裝到request對象中
		//從request獲取這些信息
		//表單數據是這樣提交的,POST請求,在請求體中提交,數據格式:username=admin&password=123...
		/* Map<String,String[]>
		 * key              value
		 * ---------------------------
		 *username          {"admin"}
		 *password          {"134"}
		 *interest          {"sport","music"}
		 *......
		 * */
		String  username= request.getParameter("username");
		String password= request.getParameter("password");
		String sex=request.getParameter("sex");
		//String interest=request.getParameter("interest");
		String grade= request.getParameter("grade");
		String introduce=request.getParameter("introduce");
		
		System.out.println(username);
		System.out.println(password);
		System.out.println(sex);
		//System.out.println(interest);
		System.out.println(grade);
		System.out.println(introduce);
		//獲取所有的興趣愛好
		String[] interest=request.getParameterValues("interest");
		for(String in:interest) {
			System.out.println(in);
		}
		
		//獲取整個參數Map集合
		Map<String,String[]>parameterMap=request.getParameterMap();
		Set<String> names=parameterMap.keySet();
		for(String name:names) {
			String[] values = parameterMap.get(name);
			System.out.println(name+"=");
			for(String value :values) {
				System.out.print(value+" ");
			}
			System.out.println();
		}
		//獲取參數Map集合所有的key
		Enumeration<String> names1=request.getParameterNames();
		while(names1.hasMoreElements()) {
			String name=names1.nextElement();
			System.out.println(name);
		}
	}
	
}

HttpServletRequest是一個怎樣的範圍呢?
HttpServletRequest類型的變量通常命名爲:request,代表當前的本次請求一次請求對應一個request對象,100個請求對應100個請求對象。

請求範圍是極小的,request只能完成在同一次請求中傳遞數據。

ServletContext 應用範圍,可以跨用戶傳遞數據。

ServletRequest 請求範圍,只能在同一個請求中傳遞數據【可以跨Servlet傳遞數據,但是這個Servlet必須在同一個請求中】優先選擇request範圍。

解決項目中的中文亂碼問題:
1.亂碼出現在什麼位置?
數據 “傳遞”過程中的亂碼
數據 “展示”過程中的亂碼
數據 “保存”過程中的亂碼

2.數據保存過程中的亂碼
最終保存到數據庫表中的時候,數據出現亂碼。
導致數據保存過程中的亂碼包括以下兩種情況:
第一種情況:在保存之前,數據本身是亂碼,保存到數據表中的時候一定是亂碼。
第二種情況:保存之前,數據不是亂碼,但是由於數據庫不支持中文,保存後出現亂碼。

3.數據展示過程中的亂碼:
顯示數據出現亂碼。
解決方案:
設置響應的內容類型,以及對應的字符編碼方式:
response.setContextType(“text/html;charset=UTF-8”);

如果沒有執行java程序的html
設置爲<meta content="text/html"; charset="UTF-8">

4.數據傳遞過程中的亂碼:
將數據從瀏覽器發送給服務器的時候,服務器接收到的數據是亂碼。

“市場部”對應的ISO-8859-1的編碼:%E5%B8%…
ISO-8859-1是國際標準編碼,不支持中文編碼,兼容ASCII碼,又被稱爲latin1編碼。
不管哪個國家的文章,在瀏覽器發送給服務器的時候,都會採用ISO-8859-1的編碼方式發送。

發送給web服務器之後,web服務器不知道這些數據之前是什麼類型的文字。所以會出現亂碼。

解決數據傳遞過程中的亂碼:
第一種解決方案:
萬能方式,既能夠解決POST請求亂碼,又能解決GET請求亂碼。
先將服務器中接受到的數據採用ISO-8859-1的方式解碼,迴歸原始狀態,再給定一種支持簡體中文的編碼方式重新編碼組裝。
在這裏插入圖片描述
第二種解決方式:
調用request的setCharacterEncoding方法,但只適合POST
request.setCharacterEncodeing(“UTF-8”);
String dname =request.getParameter(“dname”);
System.out.println(dname);

在這裏插入圖片描述

Servlet線程安全問題

1.Servlet是單實例多線程環境下運行的。

2.什麼時候程序存在線程安全問題。
多線程併發
有共享的數據
共享數據有修改操作

3.在JVM中,哪些數據可能會存在線程安全問題?
局部變量內存空間不共享,一個線程一個棧,局部變量在棧中存儲,局部變量不會存在線程安全問題

常量不會被修改,所以常量不會存在線程安全問題。

所有的線程共享一個堆。
堆內存中new出來的對象在其中存儲,對象內部有“實例變量”,所以“實例變量”的內存多線程是共享的。實例變量多線程共同訪問,並且涉及到修改操作的時候就會存在線程安全問題。

所有線程共享一個方法區
方法區中有靜態變量,靜態變量的內存也是共享的,若涉及到修改操作,靜態變量也存在線程安全問題。

**4.線程安全問題不止是體現在JVM中,**還有可能發生在數據庫中,例如:多個線程共享同一張表,並且同時去修改表中的記錄,那麼就存在線程安全問題。

怎麼解決數據庫表中數據的線程安全問題?
第一種方案:使用synchronized關鍵字
第二種方案:行級鎖【悲觀鎖】
第三種方案:事務隔離級別,如:串行化
第四種方案:樂觀鎖。

5.怎麼解決線程安全問題?
不使用實例變量,儘量使用局部變量。

若必須使用實例變量給,那麼我們可以考慮將該對象變成多例對象,一個線程一個java對象,實例變量的內存也不會共享。

若必須使用單例,那就只能使用synchronized線程同步機制,線程一旦排隊執行,則吞吐量降低,降低用戶體驗。

6.Servlet怎麼解決線程安全問題?
不使用實例變量,儘量使用局部變量。

Servlet必須是單例的,所以剩下的方式只能考慮synchronized,線程同步機制。

關於web系統中資源跳轉
跳轉包括兩種方式:
轉發:forward
重定向:redirect

轉發:(你沒錢向朋友借錢,朋友沒錢,他去借錢然後給你)
從一個java源程序轉到另一個源程序。

在這裏插入圖片描述
重定向:將路徑中心發送給了瀏覽器( 相當於一個超鏈接)
在這裏插入圖片描述
轉發和重定向的區別:
**相同點:**都可以完成資源跳轉。
不同點:
轉發是request對象觸發的
重定向是response對象觸發的。
轉發是一次請求,瀏覽器地址欄上的地址不會變化。
重定向是兩次請求,瀏覽器地址欄上的地址發生變化。

重定向的路徑需要加webapp的根路徑
轉發是在本項目內部完成資源跳轉。
重定向可以完成跨app跳轉資源。

跳轉的下一個資源可以是什麼?
web服務器任何資源。
什麼時候採用轉發,什麼時候採用重定向?
若想跨app跳轉,必須使用重定向。

希望在下一個資源中從request範圍中將數據取出,必須使用轉發。

重定向可以解決瀏覽器刷新問題。
重定向的原理是什麼?
在這裏插入圖片描述

解決瀏覽器刷新問題
重定向可以解決頁面刷新的問題:
刷新只會刷新第二個請求:執行第二條請求語句。

而轉發刷新的是第一個請求。
在這裏插入圖片描述

04.登錄

完成用戶登錄
在這裏插入圖片描述

練習:完成網頁端員工信息的增刪改查。

05.Cookie

1.什麼是 Cookie?
Cookie,有時也用其複數形式 Cookies。類型爲“小型文本文件”,是某些網站爲了辨別用戶身份,進行Session跟蹤而儲存在用戶本地終端上的數據(通常經過加密),由用戶客戶端計算機暫時或永久保存的信息。

Cookie 是一些數據, 存儲於你電腦上的文本文件中。

當 web 服務器向瀏覽器發送 web 頁面時,在連接關閉後,服務端不會記錄用戶的信息。

Cookie 的作用就是用於解決 “如何記錄客戶端的用戶信息”:

當用戶訪問 web 頁面時,他的名字可以記錄在 cookie 中。
在用戶下一次訪問該頁面時,可以在 cookie 中讀取用戶訪問記錄。
Cookie 以名/值對形式存儲,如下所示:

username=John Doe

當瀏覽器從服務器上請求 web 頁面時, 屬於該頁面的 cookie 會被添加到該請求中。服務端通過這種方式來獲取用戶的信息。

也可以將數據保存在服務器端,但是需要用戶登錄。

2.網站上的十天免登錄功能:
將賬戶信息保存在客戶端硬盤上,並且壽命爲10天。

網吧有還原卡,進行還原。無需擔心。

3.Cookie的保存位置
Cookie是保存在瀏覽器客戶端上的
Cookie也可以保存在瀏覽器的緩存中,瀏覽器關閉Cookie消失。
Cookie也可以保存在客戶端的硬盤文件中,瀏覽器關閉Cookie還在,除非Cookie失效。

4.Cookie只有在javaweb中才有嗎?
Cookie不止實在javaweb中存在。
只要是web開發,只要是B/S架構的系統,只要是HTTP協議,就有Cookie的存在。
Cookies這種機制是Http協議規定的。

5.Cookie實現的功能,常見的有哪些?
十天免登錄
購物車數據等。

6.Java中Cookie被當作類來處理,使用new運算可以創建Cookie對象,而且Cookie由兩部分組成,分別是Cookie的name和value,name和value都是字符串類型String。

7.java程序中怎麼創建Cookie?
Cookie cookie=new Cookie(String CookieName,String cookieValue);

8.服務器可以一次向瀏覽器發送多個Cookie.

9.默認情況下,服務器發送Cookie給瀏覽器之後,瀏覽器將Cookie保存在緩存中,只要不關閉瀏覽器,Cookie永遠存在,並且有效。當瀏覽器關閉之後,緩存中的Cookie被清除了。

10.在瀏覽器客戶端無論是硬盤文件中還是緩存中保存的Cookie,什麼時候會再次發送給服務器呢?

瀏覽器會不會提交發送這些Cookie給服務器,和請求路徑有關係。
不同的路徑會發送提交不同的Cookie。

11.默認情況下Cookie會和哪些路徑綁在一起?

/webapps/test/xxx
請求服務器,服務器生成Cookie,並將Cookie發送給瀏覽器客戶端。

這個瀏覽器中的Cookie會默認和“test/”這個路徑綁定在一起。
也就是說,以後只要發送“test/”請求,Cookie一定自動提交給服務器。

如果是:/webapps/test
請求服務器,服務器生成Cookie,並將Cookie發送給瀏覽器客戶端。
這個瀏覽器中的Cookie會默認和“webapps/”這個路徑綁定在一起。
也就是說,以後只要發送“webapps/”請求,Cookie一定會提交給服務器。

12.其實路徑可以指定的,可以通過java程序進行設置,保證Cookie和某個特定的路徑綁定在一起。
指定路徑後,Cookie將和指定路徑綁定在一起。
在這裏插入圖片描述
13.默認情況下,沒有設置Cookie的有效時間,該Cookie被默認保存在瀏覽器的緩存中,只要瀏覽器不關閉Cookie存在 ,只要關閉瀏覽器Cookie消失,我們可以通過設置Cookie的有效時長,以保證Cookie保存在硬盤文件當中。但是這個有效時長必須是>0的,換句話說,只要設置Cookie的有效時長大於0,則該Cookie會被保存在客戶端硬盤文件中。有效時長過去後,硬盤中的,則硬盤當中的Cookie失效。
Cookie有效時長=0不會直接被刪除,Cookie有效時長<0不會被存儲,Cookie有效時長>0存儲在硬盤文件當中。
設置Cookie的有效時長
Cookie1.setMaxAge(6060);
Cookie2.setMaxAge(60
60*24); 1小時有效

14.瀏覽器提交Cookie給服務器,服務器怎麼接收Cookie?

從request對象中獲取所有提交的Cookie。

Cookie[] cookies = request.getCookies()if(cookies!=null)
for(Cookie cookie :cookies){
String cookieName=cookie.getName();
String cookieValue=cookie.getValue();
System.out.println(cookieName+"="+cookievalue);
}

15.cookies存在有效時間,決定了存放位置,瀏覽器可以禁用Cookie。
表示服務器發送過來的Cookie,瀏覽器不做處理。

用Cookie實現十天免登錄

請看原項目:https://download.csdn.net/download/jiahuan_/12502995
實現了表單驗證,控制用戶名規範。

待改進之處,頁面的美化和重名問題。
在這裏插入圖片描述

關於路徑的總結

1.關於url-pattern的編寫方式和路徑的總結
1.路徑的編寫形式:

//超鏈接
<a href="/項目名/資源路徑"></a>

//表單
<form action="/項目名/資源路徑"></form>

//重定向
response.sendRedirect("項目名/資源路徑");

//轉發
request.getRequestDispatcher("/資源路徑").forward(request,response);

//歡迎頁面
<welcome-file-list>
	<welcome-file>資源路徑</welcome-file>
</welcome-file-list>

//servlet路徑
<servlet>
	<servlet-name>hello</servlet-name>
	<servlet-class>part1.Helloservlet<servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>hello<servlet-name>
	<url-pattern>/資源路徑</url-pattern>
</servlet-mapping>

//Cookie設置Path
cookie.setPath("/項目名/資源路徑");

//ServletContext
ServletContext application =config.getServletContext();
application.getRealPath("/WEB-INF/Classes/db.properties");
application.getRealPath("/資源路徑");

2.url-pattern路徑的編寫方式
1.url-pattern可以編寫多個
精確匹配的方式

<servlet-mapping>
	<servlet-name>hello<servlet-name>
	<url-pattern>/hello</url-pattern>
	<url-pattern>/system/hello</url-pattern>
</servlet-mapping>

擴展匹配的方式
以abc開始的即可。

<url-pattern>/abc/*</url-pattern>

後綴匹配

<url-pattern>*.action</url-pattern>

全部匹配

<url-pattern>/*</url-pattern>

06.HttpSession

HttpSession簡介
HttpSession是Java平臺對session機制的實現規範,因爲它僅僅是個接口,具體到每個web應用服務器的提供商,除了對規範支持之外,仍然會有一些規範裏沒有規定的細微差異。

JSP利用servlet提供的HttpSession接口來識別一個用戶,存儲這個用戶的所有訪問信息。

默認情況下,JSP允許會話跟蹤,一個新的HttpSession對象將會自動地爲新的客戶端實例化。禁止會話跟蹤需要顯式地關掉它,通過將page指令中session屬性值設爲false來實現

1.Session表示會話,不止是在javaweb中存在,只要是web開發,都有會話這種機制。

2.在java中會話對應的類型是:javax.servlet.http.HttpSession,簡稱session

3.Cookie可以將會話保存在客戶端,HttpSession可以將會話狀態保存在服務器端。

4.HttpSession對象是一個會話級別的對象,一次會話對應一個HttpSession對象。

在這裏插入圖片描述
5.什麼是一次會話?
可以理解爲:打開瀏覽器發送多次請求,直到瀏覽器關閉。

6.在會話過程中,web服務器一直爲當前這個用戶維護着一個會話對象/HttpSession

7.在WEB容器中,WEB容器維護了大量的HttpSession對象,換句話說,在WEB容器中應該有一個"session列表"。

思考:爲什麼當前會話中的每一次請求可以獲取到屬於自己的會話對象

瀏覽器首次發送請求,服務器會創建一個HttpSession對象,該對象代表一次會話。

同時生成HttpSesion對象對應的Cookie對象,並且Cookie對象的name是JSESSIONID。Cookie的value是32位長度的字符串。

服務器將Cookie的value和HttpSession對象綁定到session列表中。

服務器將Cookie完整的發送給瀏覽器客戶端。

瀏覽器客戶端將Cookie保存到緩存中,只要瀏覽器不關閉,Cookie不會消失,當再次發送請求的時候,會自動提交緩存當中的Cookie.服務器收到Cookie,驗證Cookie的的name確實是:JSESSIONID,獲取Cookie的value,通過Cookie的value區檢索session列表。

瀏覽器發送Cookie給服務器,通過Cookie的值去找session對象。

8.和HttpSession對象關聯的這個Cookie的name是比較特殊的,在java中叫做:jsessionid。

** 9.瀏覽器禁用Cookie會出現什麼問題?怎麼解決?**
瀏覽器禁用Cookie,則瀏覽器緩存中不再保存Cookie。
導致在同一個會話中,無法獲取到對應的會話的對象。每次獲取的會話對象都是新的。

瀏覽器禁用Cookie之後,若還想拿到Session對象,必須重寫URL機制,怎麼重寫URL?

URL;jsessionid=xxxxxxxxxxxxxxxxx

重寫URL會給編程帶來難度。所以儘量不要禁用。
10.瀏覽器關閉之後,服務器對應的session對象會被銷燬嗎?爲什麼?
不會!
因爲B/S架構的系統基於HTTP協議,而HTTP協議是一種無連接/無狀態的協議。
請求的瞬間和服務器之間的通道是打開的,請求響應結束後,通道關閉。
這樣做的目的是降低服務器的壓力。

11.session對象在什麼時候被銷燬?
web系統中引入session超時的概念。
當很長一段時間(這個時間可以配置)沒有用戶在訪問該session對象,此時session對象超時,web服務器自動回收session對象。

12.什麼是一次會話?
一般講:瀏覽器打開進行一些操作後,關閉瀏覽器。
本質上:瀏覽器session被創建到session對象超時之後銷燬。

web.xml設置超時時間,默認爲30分鐘

<session-config>
<session-timeout>120</session-timeout>
</session-config>

13.HttpSession接口常用的方法

//獲取當前的session,獲取不到則新建session
HttpSession session = request.getSession();
//獲取當前的session,獲取不到,則新建session
HttpSession session = request.getSession(true);
//獲取當前的session,獲取不到,則返回null

HttpSession session = request.getSession(flase);
//
void setAttribute(String name Object value);

//
Object getAttribut(String name)

//
void removeAttribute(String name);

//銷燬session
void invalidate();

14.ServletContext,HttpSession,HttpServletRequest接口的對比:
14.1 以上都是範圍對象:
ServletContext application;是應用範圍。
HttpSession session是會話範圍。
HttpServletRequest request;是請求範圍。

14.2 三個範圍的排序
application>session>request

14.3 application完成跨會話共享數據、session完成跨請求傳遞數據,但是這些請求必須在同一個會話當中。
request完成跨Servlet共享數據,但是這些Servlet必須在同一個請求當中【轉發】。

14.4 使用的原則:從小到大嘗試,優先使用小範圍。
如:登入成功這個狀態保存至sessoin對象中。
登錄成功狀態不能保存到request範圍中,因爲一次請求對應一個新的request對象。
登錄成功狀態也不能保存到application範圍中,因爲登錄成功狀態是屬於會話級別的,不能所有用戶共享。

07.實現記錄登錄狀態

練習:
需要實現的功能:
1.登錄
2.登錄成功後將此“已登錄”狀態保存。
3.實現“顯示員工列表”功能。
4.當用戶點擊“顯示員工列表”的時候,驗證用戶是否已登錄,已登錄繼續顯示員工列表,沒有登錄則跳轉到登錄頁面。
5.退出系統功能。

請看原項目:https://download.csdn.net/download/jiahuan_/12505146

部分截圖:
在這裏插入圖片描述
待改進之處,查詢信息頁面的美化
注意:退出用戶登錄這裏直接採取了,銷燬session的方法,並且直接寫在了登錄成功查詢信息的源程序,這樣在重新訪問員工信息時需要再次登錄,因爲session已被銷燬。建議可以寫一個退出按鈕,再轉到銷燬session的源程序,這樣當未點擊退出時,再次訪問時,可以直接訪問員工信息。

“ 生活是不公平的,不管你的境遇如何,你只能全力以赴。任何時候,不要過分去糾結公平與否,全力以赴,無怨無悔,輕鬆笑對得與失。”我是夢陽辰,與你共進退!別忘記素質三連哦!

關注公衆號【輕鬆玩編程】回覆關鍵字“電子書”,“計算機資源”,“Java從入門到進階”,”JavaScript教程“,“算法”,“Python學習資源”,“人工智能”等即可獲取學習資源。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章