2、JSP實現資料傳遞和儲存

NemophilistPro發表於2020-09-25


前言

掌握request和response的使用
解決頁面中出現的中文亂碼
掌握轉發和重定向的區別
掌握session存取資料
理解cookie
理解application


提示:以下是本篇文章正文內容,下面案例可供參考

1、九個內建物件

JSP已經準備好的,可以直接使用的物件
  1. 請求物件:request
  2. 輸出物件:out
  3. 響應物件:response
  4. 應用程式物件:application
  5. 會話物件:session
  6. 頁面上下文物件:pageContext
  7. 頁面物件:page
  8. 配置物件:config
  9. 異常物件:exception

2、request

2.1 獲取表單提交的資料

public String getParameter(String name)

示例
HTML程式碼:

<input type="text" name="userName" />

JSP程式碼:

String userName= request.getParameter("userName");

2.2 獲取同名的多個引數

示例

<input type="checkbox"  name="mailId"  value="10001" />
<input type="checkbox"  name="mailId"  value="10002" />
<input type="checkbox"  name="mailId"  value="10003" />
<input type="checkbox"  name="mailId"  value="10004" />
<input type="checkbox"  name="mailId"  value="10005" />

解決方法:
通過getParameterValues()獲取同名陣列


```java
String[ ] mailIds=request.getParameterValues("mailId");
if(mailIds!=null&&mailIds.length!=0){
	//迴圈mailIds訪問提交的資料
}else{
	//未提交與引數mailId相關的資料
}

2.3 get與post區別

比較項Getpost
引數出現在URL中
長度限制
安全性
URL可傳播

2.3.1 初級回答:

1.get是從伺服器上獲取資料,post是向伺服器傳送資料,??
2.get傳送的資料量較小,不能大於2KB。post傳送的資料量較大,一般被預設為不受限制。
3.get安全性非常低,post安全性較高。但是執行效率卻比Post方法好。
4.在進行檔案上傳時只能使用post而不能是get。

2.3.2 中級回答:【推薦】

  1. get是從伺服器上獲取資料,post是向伺服器傳送資料。??
  2. get是把引數資料佇列加到提交表單的ACTION屬性所指的URL中,值和表單內各個欄位一一對應,在URL中可以看到。post是通過HTTP post機制,將表單內各個 欄位與其內容放置在HTML HEADER內一起傳送到ACTION屬性所指的URL地址。使用者看不到這個過程。
  3. 對於get方式,伺服器端用Request.QueryString獲取變數的值,對於post方式,伺服器端用Request.Form獲取提交的資料
  4. get傳送的資料量較小,不能大於2KB。post傳送的資料量較大,一般被預設為不受限制。但理論上,IIS4中最大量為80KB,IIS5中為100KB。
  5. get安全性非常低,post安全性較高

2.4、 request物件常用方法

方法名稱說明
String getParameter(String name)根據表單元件名稱獲取提交資料
String[ ] getParameterValues(String name)獲取表單元件對應多個值時的請求資料
void setCharacterEncoding(String charset)指定每個請求的編碼
RequestDispatcher getRequestDispatcher(String path)返回一個RequestDispatcher物件,該物件的forward( )方法用於轉發請求

2.5、中文亂碼解決

JSP中預設使用的字元編碼方式:iso-8859-1,不支援中文
常見的支援中文的編碼方式

編碼方式收錄的字元
gb2312常用簡體漢字
gbk簡體和繁體漢字
utf-8所有國家需要的字元

2.5.1 post:

設定請求和響應的編碼方式

1.	request.setCharacterEncoding("utf-8");
2.	response.setCharacterEncoding("utf-8");
3.	<%@ page language="java" contentType="text/html; charset=utf-8"%>

2.5.2 get:

  1. 治標的方法:new String( s.getBytes(“iso-8859-1”), “utf-8” );
  2. 治本的方法:配置tomcat\conf\server.xml檔案
    URIEncoding=“UTF-8”
    useBodyEncodingForURI=“true”
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>

2.5.3 Cookie中解決中文異常問題

  1. 對要新增cookie的欄位進行設定編碼格式使用(URLEncoder.encode(String s, String enc))
    示例:
userName=URLEncoder.encode(userName,"utf-8");
  1. 以上可以解決異常問題,但在獲取cookie時很有可能出現亂碼,所以需在獲取cookie值時設定解碼方式(URLDecoder.decode(String s, String enc))
    示例:
name = URLDecoder.decode(name,"utf-8");

2.6、 在請求中存取屬性

2.6.1 在請求中儲存屬性(作用域:一次請求)

public void setAttribute(String name,Object o)

說明:
String name:屬性名
Object o :屬性值
示例:

request.setAttribute("mess", "註冊失敗");

2.6.2在請求中獲取屬性

public Object getAttribute(String name)

說明:
String name:屬性名
注意:
1、在使用屬性值的時候要做非空判斷,否則會出現空指標異常
2、它的返回值型別是Object型別,需要做資料型別的轉換

String mess=(String)request.getAttribute("mess");
if(mess!=null){
//在請求中取到"mess"屬性對應的屬性值,正常使用mess資料
}else{
//在請求中沒有取到"mess"屬性對應的屬性值,使用備選方案
}

2.7、轉發與重定向

2.7.1 轉發

RequestDispatcher物件
forward()方法

語法:

1、request.getRequestDispatcher("url").forward(request, response)
2<jsp:forward page="url" />

本質:
客戶端第一次請求(URL1),服務端(URL1)轉發請求到響應頁面(URL2)進行處理。
所以是此時請求的URL在處理並響應。此時URL沒有改變
轉發的工作方式:
在這裡插入圖片描述

2.7.2重定向

將使用者請求重新定位到一個新的URL
response.sendRedirect("url")

重定向的工作方式:
在這裡插入圖片描述

本質:將使用者請求重新定位到一個新的URL
客戶端第一次請求服務端(URL1),服務端(URL1)響應給客戶端新的(URL2)
客戶端第二次請求服務端,(URL2),服務端(URL2)進行處理並響應。
所以重定向後的URL發生了改變。

2.8、轉發與重定向的區別

比較項轉發重定向
URL變化否 是
重新發出請求不會
是否攜帶請求
目標URL要求僅本Web應用任意URL

注意:重定向是客戶端行為,轉發是伺服器行為

例子說明:
假設你去辦理某個執照,
重定向:你先去了A局,A局的人說:“這個事情不歸我們管,去B局”,然後,你就從A退了出來,自己乘車去了B局。
轉發:你先去了A局,A局看了以後,知道這個事情其實應該B局來管,但是他沒有把你退回來,而是讓你坐一會兒,自己到後面辦公室聯絡了B的人,讓他們辦好後,送了過來。

2.8.1 引數傳遞區別

2.8.1.1 轉發:
public void setAttribute(String name,Object o)

使用轉發進行屬性轉遞時,轉發給其他URL處理時仍然屬於一次請求,所以可以獲得引數

2.8.1.2 重定向:

重定向使用屬性傳遞時,由於重定向的本質是2個請求,則第一次請求所攜帶的引數在的二次不會再次攜帶。
可用擴大作用域來進行攜帶引數,如下例子:

response.sendRedirect(request.getContextPath()+"/index.jsp");

2.8.2 路徑

JSP頭部引用如下:

<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

用來表明當前頁面的相對路徑所使用的根路徑,也就是專案名稱
示例:http://localhost:8085/Info_System/user/user_info.jsp

1.request.getSchema();可以返回當前頁面所使用的協議,就是”http”
2.request.getServerName();返回當前頁面所在伺服器的名字,就是上面例子中的”localhost”
3.request.getServerPort();返回當前頁面所在伺服器的埠號,就是上面例子中的”80854.request.getContextPath();返回當前頁面所在的應用的名字(專案名),就是上面例子中的”Info_System”

超連結的路徑例子如下:

<base href="<%=basePath%>" />

2.8.3 Cookie使用的區別

2.8.3.1 轉發

第一次請求到服務端時,客戶端沒有cookie,轉發到其他頁面處理時,此時都屬於一次的請求範圍,服務端並沒有返回cookie。當服務端響應完成後,客戶端拿到了cookie,所以重新整理進行重新請求時可以拿到cookie的引數

2.8.3.2 重定向

第一次請求到服務端時,服務端返回cookie即服務端拿到cookie
第二次請求到服務端時,其request物件裡已經包含了cookie

3、Session

3.1 session儲存資訊(作用域:一個會話)

  1. 一個會話就是瀏覽器與伺服器之間的一次通話
  2. 會話可以在多次請求中儲存和使用資料
    在這裡插入圖片描述

設定語法:

public void setAttribute(String name, Object value);

示例
用法:session.setAttribute("userName", "張三丰");
獲取資訊語法:

public Object getAttribute(String name);

示例
用法:String userName=(String)session.getAttribute("userName");
說明:Object value的值可用request.getParameter()獲得session的工作方式
每個session都有一個唯一的sessionid

public String getId();
session.getId();

在這裡插入圖片描述

說明:

cookie禁用後,session是否能使用(摘錄網路內容,供大家參考)
URL重寫
表單提交隱藏域

cookie禁用後,session能否使用的問題
sessionid是儲存在cookie中的,解決方案如下:
Session URL重寫,保證在客戶端禁用或不支援COOKIE時,仍然可以使用Session

session機制。session機制是一種伺服器端的機制,伺服器使用一種類似於雜湊表的結構(也可能就是使用雜湊表)來儲存資訊。

當程式需要為某個客戶端的請求建立一個session時,伺服器首先檢查這個客戶端的請求裡是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端建立過session,伺服器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含session id,則為此客戶端建立一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字串,這個session id將被在本次響應中返回給客戶端儲存。 儲存這個session id的方式可以採用cookie,這樣在互動過程中瀏覽器可以自動的按照規則把這個標識發揮給伺服器。一般這個cookie的名字都是類似於 SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞迴伺服器。 經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的後面。還有一種技術叫做表單隱藏欄位。就是伺服器會自動修改表單,新增一個隱藏欄位,以便在表單提交時能夠把session id傳遞迴伺服器。比如:

URL重寫:

http://www.test.com/test;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764

3.2 session的清除和過期

session的資料是在伺服器端的,伺服器儲存的會話資料量會越來越大,從而導致效能問題
若沒有清理機制,會導致效能問題或伺服器崩潰
程式主動清除session資料
伺服器主動清除長時間沒有再次發出請求的session

3.2.1 程式主動清除session資料

作用:
可用作登出
1、 設定會話失效:session.invalidate();
說明:直接使用
2、 移除會話的一個屬性
語法:

public void removeAttribute(String name); 

用法:session.removeAttribute("userName");
說明:需指定屬性

3.2.2 定時清除session資料

伺服器主動清除長時間沒有再次發出請求的session
設定會話過期時間
方法一:

public void setMaxInactiveInterval(int interval); 

說明:
int interval:單位:秒
方法二:

	<session-config>
       <session-timeout>30</session-timeout>
</session-config>

說明:
1、 在web.xml中設定session的有效期
2、 中間的單位是秒
注意:
1、設定session過期時間後,在同一個頁面超過時間,進行重新整理,此時sessionId發生改變,說明原來的會話已經過期,現獲取的是新的session。
2、session是服務端的行為

4、cookie

作用:自動填寫使用者名稱
cookie以檔案方式儲存資料

4.1 新增資料

public void addCookie(Cookie cookie)

4.2獲取資料

public Cookie[] getCookies()

4.3 設定有效期,單位秒,不設定則關閉瀏覽器失效

public void setMaxAge(int expiry)

4.4 使用者可以禁用cookie和解決

解決方案:
Session URL重寫,保證在客戶端禁用或不支援COOKIE時,仍然可以使用Session

session機制。session機制是一種伺服器端的機制,伺服器使用一種類似於雜湊表的結構(也可能就是使用雜湊表)來儲存資訊。

當程式需要為某個客戶端的請求建立一個session時,伺服器首先檢查這個客戶端的請求裡是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端建立過session,伺服器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含session id,則為此客戶端建立一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字串,這個session id將被在本次響應中返回給客戶端儲存。 儲存這個session id的方式可以採用cookie,這樣在互動過程中瀏覽器可以自動的按照規則把這個標識發揮給伺服器。一般這個cookie的名字都是類似於 SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞迴伺服器。 經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的後面。還有一種技術叫做表單隱藏欄位。就是伺服器會自動修改表單,新增一個隱藏欄位,以便在表單提交時能夠把session id傳遞迴伺服器。比如:

<form name="testform”" action="/xxx”"> <input type="hidden”" name="jsessionid”" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764″”> <input type=”"text”"> </form>

URL重寫:

http://www.test.com/test;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764

4.5 設定有效路徑:整個工程可用訪問cookie,否則僅本路徑和子路徑訪問

cookie.setPath("/");

4.6 示例

4.6.1 新建Cookie並設定

			//給中文新增cookie編碼(設定編碼集為utf-8),且儘量不存中文
			userName=URLEncoder.encode(userName,"utf-8");
			//Cookie 新建物件,記錄使用者名稱,自動填寫功能,鍵值對構造器
			Cookie cookie = new Cookie("userName",userName);
			//設定Cookie有效時間,單位秒,不設定則關閉瀏覽器失效
			cookie.setMaxAge(20);
			//整個工程可用訪問cookie,否則僅本路徑和子路徑訪問
			cookie.setPath("/");
			//給響應新增Cookie
			response.addCookie(cookie);

注意:要採用重定向發生請求,即可“一次”拿到cookie。而轉發需再重新整理

4.6.2 獲取cookie的方式

<%
		//使用cookie獲取資料,填充到文字框
		String name = "";
		//獲取Cookie陣列
		Cookie[] cookies = request.getCookies();
		//非空判斷
		if (cookies != null && cookies.length != 0) {
		//遍歷cookie
			for (int i = 0; i < cookies.length; i++) {
		//測試cookie的key值
				System.out.println(cookies[i].getName());
				if (cookies[i].getName().equals("userName")) {
		//獲取cookie的value值
					name = cookies[i].getValue();
		//對cookie的value值解碼設定為utf-8
					name = URLDecoder.decode(name,"utf-8");
				}
			}
		}
	
	%>

5、application

作用:統計頁面的訪問次數
分析

  1. 每個使用者都需要使用訪問次數
  2. application可在整個專案中共享使用資料
  3. 使用application實現計數器
  4. 每次訪問該頁面,計數器加1

方法

public void setAttribute(String name, Object object);
public Object getAttribute(String name);

示例:

<%
//通過application設定count屬性,並獲取值
		Integer count = (Integer) application.getAttribute("count");
//非空判斷,若為空,則是第一次訪問,設定count=1
		if (count == null) {
			application.setAttribute("count", 1);
		} else {
//非空設定count的值加一
			application.setAttribute("count", count + 1);
		}
//獲取count的值,並輸出
		count = (Integer) application.getAttribute("count");
		out.print("頁面被訪問了" + count + "次");
	%>

6、三個物件對比

6.1 相同點

  • 都可以儲存屬性

6.2 不同點

  1. request中儲存的資料僅在一個請求中可用
    2.

  2. session中儲存的資料在一個會話的有效期內可用
    在這裡插入圖片描述

  3. application中儲存的資料在整個Web專案中可用

在這裡插入圖片描述

相關文章