JSP WEB開發(一) JSP語言基礎

目錄

JSP

JSP簡介:

JSP頁面

JSP運行原理

JSP腳本元素

JAVA程序片

局部變量?

全局變量和方法的聲明

全局變量

方法的聲明

?程序片執行特點

synchronized關鍵字

表達式

JSP指令標記

page指令

include指令

JSP動作標記

?JSP動作元素include和include指令的區別

param動作標記

forward動作標記

?JSP四個主要的內置對象

?request內置對象

※ URL地址重寫

表單

表單操作

GET 方式

POST 方式

GET 和 POST 的區別

response對象

☆頁面跳轉

session對象

?取得Session Id

處理數據

☆“登陸及注銷”模塊


JSP

JSP簡介:

基于B/S模式的網絡程序核心就是設計服務器端的web應用程序。

JSP(Java Server Pages)是基于Java 語言的一種Web應用開發技術,利用這一技術可以建立安全、跨平臺、易維護的動態頁面應用程序。

利用JSP技術,可以實現動態頁面與靜態頁面的分離,便于擴展和維護。

JSP頁面

一個jsp頁面包含:普通的HTML標記符和使用”<%”” %>”標記符加入的java程序片

JSP頁面按照文本文件保存,擴展名是.jsp

JSP運行原理

服務器上的jsp頁面被第一次請求執行時,jsp引擎首先將jsp頁面文件轉換成一個java文件,并編譯這個java文件生成字節碼文件,然后執行字節碼文件響應客戶的請求。

當該jsp頁面再次被請求執行時,JSP引擎將直接執行字節碼文件來響應客戶請求。

如果對jsp頁面進行了修改、保存,服務器將生成新的字節碼文件。

JSP腳本元素

JAVA程序片

在“<% 和“%>”標記符號間插入Java程序片

Java程序片是指在JSP頁面中使用的Java代碼片段,它們被包圍在<%%>標簽內。這些代碼片段會在服務器端執行,并生成動態內容。程序片可以包含變量聲明、表達式和控制語句

<%
int count = 0;
for (int i = 0; i < 5; i++) {count++;out.println("Hello, World! " + count);
}
%>

在這個例子中,我們聲明了一個整型變量count,并在循環中遞增并打印出來。

局部變量?

程序片中聲明的變量稱為JSP頁面的局部變量

局部變量是在方法或程序片中聲明的變量,它的作用域只限于該方法或程序片。一旦方法或程序片結束,局部變量就會被釋放。在JSP中,程序片內的變量就是局部變量,因為它們的作用域僅限于該程序片。

線程安全性:由于JSP頁面可能會并發地被多個線程訪問,因此必須考慮線程安全問題。如果多個線程同時訪問同一個程序片,那么局部變量可能會引發競爭條件。例如,假設兩個線程同時訪問上面的例子,它們都嘗試增加count的值,但結果可能是不確定的,因為它們可能互相覆蓋對方的結果。

分別在不同的線程中執行:JSP頁面可能會被多個線程并發訪問,這意味著程序片中的代碼可能會在不同的線程中執行。這可能導致一些問題,尤其是涉及到共享資源時。為了避免這些問題,應該避免在程序片中使用全局變量或共享狀態,而是盡可能使用局部變量。

全局變量和方法的聲明

全局變量

在“<%! 和“%>”標記符號間聲明變量

在JSP頁面中,成員變量是那些在整個頁面范圍內有效的變量。它們可以在頁面的不同部分被引用,無論<%!%>標記的位置在哪里。

<%
! int counter = 0;
%>

在這個例子中,counter就是一個成員變量,它在整個JSP頁面中都是可用的。

變量的有效范圍:成員變量的作用域是整個JSP頁面,這意味著它們可以在頁面的任何地方被訪問。相比之下,局部變量的作用域僅限于它們所在的程序片。

<%
int localCounter = 0;%><%
localCounter++; // 這里無法訪問到 localCounter,因為它是一個局部變量
%>

任何一個用戶對JSP頁面成員變量操作的結果,都會影響到其他用戶。

方法的聲明

在“<%! 和“%>”標記符號間聲明方法

在JSP頁面中,可以通過<%!%>標記來聲明方法。這些方法可以在頁面的其他部分被調用

<%
! public String getGreeting() {return "Hello, World!";
}
%>

方法的有效性:聲明的方法在JSP頁面的任何地方都可以被調用,只要它們位于<%!%>標記之間

<%
String greeting = getGreeting();
out.println(greeting);
%>

在這個例子中,我們調用了getGreeting()方法并將結果賦給greeting變量,然后將其打印出來

?方法內的變量:方法內的變量是局部變量,它們的作用域僅限于方法本身。

<%
! public void printMessage() {String message = "Hello, World!";out.println(message);
}
%>

在這個例子中,message變量僅在printMessage方法內有效。一旦方法執行完畢,message變量就被銷毀

?程序片執行特點

操作JSP頁面的成員變量:成員變量是各線程共享的變量,任何一個線程對JSP頁面成員變量操作的結果,都會影響到其他線程;

調用JSP頁面的方法:調用的方法必須是JSP頁面的方法;

聲明操作局部變量:運行在不同線程中的Java程序片的局部變量互不干擾。

PS:可將操作成員變量的方法用synchronized修飾

synchronized關鍵字

synchronized關鍵字用于控制多線程并發訪問共享資源的同步。當一個線程正在執行某個被synchronized修飾的方法或代碼塊時,其他線程必須等待該線程釋放鎖后才能繼續執行。這有助于防止數據不一致性和競態條件等問題。

使用synchronized修飾方法

要使用synchronized關鍵字,只需在其前面加上即可

public class MyClass {private int count;public synchronized void incrementCount() {count++;}
}

在這個例子中,incrementCount方法被synchronized修飾,意味著同一時間只有一個線程能執行此方法。

?JSP頁面中的synchronized

在JSP頁面中,也可以使用synchronized關鍵字來保護成員變量

<%
! int counter = 0;
public synchronized void incrementCounter() {counter++;
}
%>

表達式

在“<%= 和“%>”標記符號間插入表達式

在JSP頁面中,表達式允許你將Java表達式插入到輸出流中。表達式由<%= %>標簽包圍,其值會被轉換為字符串并寫入到響應中。

<%= someVariable %>

在這個例子中,someVariable是一個Java變量,它的值將在服務器端計算,并作為字符串輸出到客戶端瀏覽器。

字符串化:無論表達式的結果是什么類型,都會自動轉換成字符串。這意味著如果你有一個整數或布爾值,它們將分別被轉換為對應的字符串形式。

<%= 42 %> <!-- 輸出:42 -->
<%= true %> <!-- 輸出:"true" -->

該表達式必須要能求值;

不可以插入語句;

“<%=”是一個完整的符號,“<%”和“=”之間不要有空格;

JSP指令標記

page指令

用來定義或設置整個JSP頁面的一些屬性和屬性值。

<%@ page contentType="text/html;charset=UTF-8" import="java.util.*" language="java" session="false" buffer="none" autoFlush="true" isThreadSafe="false" pageEncoding="UTF-8" %>

設置了多個屬性:

  • contentType: 指定生成的HTTP響應的MIME類型和編碼。
  • import: 導入所需的Java包。
  • language: 指定腳本語言,默認為Java。
  • session: 是否啟用會話支持。
  • buffer: 設置緩沖區大小和策略。
  • autoFlush: 如果緩沖區已滿是否自動刷新。
  • isThreadSafe: 是否啟用線程安全性。
  • pageEncoding: JSP文件本身的編碼。

contentTypeimportlanguagesessionbufferautoFlushisThreadSafepageEncoding

可以用一個page指令指定多個屬性的值,也可以使用多個page指令分別為每個屬性指定值。

page指令的作用對整個頁面有效,與其書寫位置無關

多個屬性

你可以用一個page指令指定多個屬性,或者使用多個page指令分別為每個屬性指定值

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="java.util.*" %>
<%@ page language="java" %>
<%@ page session="false" %>
<%@ page buffer="none" %>
<%@ page autoFlush="true" %>
<%@ page isThreadSafe="false" %>
<%@ page pageEncoding="UTF-8" %>

include指令

include標記的作用是在JSP頁面上出現該指令的位置處靜態嵌入一個文件;

語法格式:

<%@ include file= "文件的URL" %>

注意:被嵌入的文件必須是可訪問和可使用的。嵌入文件后,必須保證新合并成的JSP頁面符合JSP語法規則,能夠成為一個JSP頁面。

示例

假設我們有一個header.jspf文件,包含了網站的頭部信息:

<header><h1>Welcome to our site!</h1>
</header>

然后,在我們的主頁home.jsp中,我們可以這樣使用include指令來包含這個文件

<%@ include file="header.jspf" %>
<body>...
</body>

這樣,每次渲染home.jsp時,header.jspf的內容就會被靜態地插入到home.jsp的相應位置。

JSP動作標記

用來在JSP頁面中動態包含一個文件,包含頁面程序與被包含的文件是彼此獨立的,互不影響。

格式

<jsp:include page= "文件的URL" />

<jsp:include page= “文件的URL”>子標記
</jsp:include>

第一種格式是簡化的版本,沒有子標記;第二種格式可以包含一些子標記,比如flushincludeParameter等。

?JSP動作元素include和include指令的區別

處理方式和處理時間上是不同的。

指令標記是在編譯階段就處理所需的文件,被處理的文件在邏輯上和語法上依賴于當前JSP頁面,優點是執行速度快。

動作標記是在JSP頁面運行時才處理文件,被處理的文件在邏輯上和語法上獨立于當前JSP頁面,優點是可以使用param子標記來傳參數

param動作標記

JSP動作標記<jsp:param>以“名字-值”的形式為其他標記提供附加信息。它不能單獨使用,必須作為<jsp:include><jsp:forward>標記的子標記來使用。

格式

<jsp:param name= "屬性名字" value= "屬性的值" />

使用場景

<jsp:include>標記一起使用時,<jsp:param>將param的值傳遞到include指令要加載的文件中去。例如:

<jsp:include page= "文件的URL"><jsp:param name= "name" value= "value"/>
</jsp:include>

forward動作標記

這個動作標記用于在服務器端將請求從當前頁面重定向到另一個頁面。

  1. 簡單的<jsp:forward>標記,不包含任何子標記:
    <jsp:forward page="要轉向的頁面" />
  2. 帶有<jsp:param>子標記的<jsp:forward>標記,可以傳遞參數給目標頁面:
    <jsp:forward page="要轉向的頁面"><jsp:param name="paramName1" value="paramValue1" /><jsp:param name="paramName2" value="paramValue2" />
    </jsp:forward>

    page屬性指定了要跳轉的目標頁面的URL。<jsp:param>子標記用于向目標頁面傳遞參數,每個<jsp:param>都有一個name和一個value屬性,分別表示參數名和參數值。

?簡單的示例,展示了如何使用<jsp:forward>動作標記來實現頁面跳轉:

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>首頁 - 頁面跳轉示例</title>
</head>
<body><h1>歡迎來到首頁!</h1><form action="forward.jsp" method="post"><input type="submit" value="點擊跳轉到目標頁面"></form>
</body>
</html>

forward.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>目標頁面 - 頁面跳轉示例</title>
</head>
<body><%// 獲取傳遞過來的參數String param1 = request.getParameter("param1");String param2 = request.getParameter("param2");%><h1>歡迎來到目標頁面!</h1><p>參數1: <%= param1 %> </p><p>參數2: <%= param2 %> </p>
</body>
</html>

在這個示例中,用戶首先訪問index.jsp頁面,然后點擊提交按鈕觸發POST請求,該請求被轉發到forward.jsp頁面。在forward.jsp頁面中,我們可以通過request.getParameter()方法獲取傳遞過來的參數并顯示出來。

?補充:超鏈接 <a> 標簽是可以傳遞參數的。通常情況下,我們在超鏈接的 href 屬性中指定目標 URL,并且可以在 URL 中添加查詢字符串來傳遞參數。

<a href="http://example.com/page?param1=value1&param2=value2">點擊這里傳遞參數</a>

當用戶點擊這個超鏈接時,瀏覽器會導航到 "http://example.com/page" 并且攜帶兩個參數:param1param2。這些參數會在目標頁面通過 GET 請求的方式發送給服務器。

?JSP四個主要的內置對象

在 JSP(JavaServer Pages)中,提供了四種不同的范圍來保存屬性(對象),這使得開發者能夠控制一個設置的對象能夠在多少個頁面中保存并繼續使用。這四種屬性范圍分別是:

  1. PageContext(page)范圍:只在一個頁面中保存屬性,跳轉之后無效。

  1. Request(request)范圍:只在一次請求中保存,服務器跳轉后依然有效。

  1. Session(session)范圍:在一次會話范圍內,無論何種跳轉都可以使用,有一定的存活周期。

? ? ? ?

  1. Application(application)范圍:在整個服務器上保存,所有用戶都可以使用。

?request內置對象

request 內置對象是最常用的一個對象之一,它代表客戶端發送的 HTTP 請求信息。

request 對象是由容器(如 Tomcat)自動創建的,它是 javax.servlet.http.HttpServletRequest 接口的實例化對象,主要用于接收客戶端發送來的請求信息,包括請求參數、頭信息等。HttpServletRequestServlet API 提供的一個接口,繼承自 ServletRequest 接口。

常見的 request 內置對象的方法及其用途:

  1. 獲取請求參數:String getParameter(String name)?—— 返回與指定名稱關聯的請求參數的值。
  2. 獲取所有請求參數:Map<String, String[]> getParameterMap()?—— 返回一個 Map,其中鍵是參數名,值是參數值數組。
  3. 獲取請求頭信息:String getHeader(String name)?—— 返回與指定名稱關聯的請求頭的值。
  4. 獲取請求方式:String getMethod()?—— 返回請求的類型(如 GET、POST 等)。
  5. 獲取請求路徑:String getRequestURI()?—— 返回請求的 URI。
  6. 獲取請求的上下文路徑:String getContextPath()?—— 返回應用程序的上下文路徑。
  7. 獲取請求的本地地址:String getLocalAddr()?—— 返回客戶端的 IP 地址。
  8. 獲取請求的本地端口號:int getLocalPort()?—— 返回客戶端的端口號。

?簡單的 JSP 示例,展示了如何使用 request 對象獲取請求

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>request內置對象示例</title>
</head>
<body><form action="request_example.jsp" method="post">用戶名:<input type="text" name="username"><br>密碼:<input type="password" name="password"><br><input type="submit" value="提交"></form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>request內置對象示例結果</title>
</head>
<body><%@ page import="java.util.Map.Entry" %><%-- 使用EL表達式 --%><%out.println("<p>用戶名:" + request.getParameter("username") + "</p>");out.println("<p>密碼:" + request.getParameter("password") + "</p>");// 使用腳本元素for (Entry<String, String[]> entry : request.getParameterMap().entrySet()) {out.println("<p>" + entry.getKey() + ": ");for (String value : entry.getValue()) {out.println(value + " ");}out.println("</p>");}%>
</body>
</html>

我們創建了一個表單,包含了兩個輸入字段:用戶名和密碼。當用戶提交表單時,請求會被發送到 request_example.jsp 頁面。在 request_example.jsp 頁面中,我們可以使用 request 對象的 getParameter() 方法來獲取表單中的參數值,并打印出來。

當使用 request 對象從客戶端接收漢字字符時,可能會遇到亂碼問題。這是因為在傳輸過程中,數據編碼格式不同導致的。要解決這個問題,我們需要設置正確的字符編碼。具體來說,你需要在讀取請求參數之前調用 request.setCharacterEncoding() 方法,設置合適的字符集。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>亂碼解決示例</title>
</head>
<body><form action="charset_example.jsp" method="post">姓名:<input type="text" name="name"><br><input type="submit" value="提交"></form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>亂碼解決結果</title>
</head>
<body><%@ page import="java.util.Map.Entry" %><%-- 使用腳本元素 --%><%request.setCharacterEncoding("GB2312"); // 設置字符編碼String name = request.getParameter("name");out.println("<p>姓名:" + name + "</p>");%>
</body>
</html>

※ URL地址重寫

URL 地址重寫是一種通過 URL 來傳遞參數的方法,而不是使用表單或 POST 請求。這種方法可以用來傳遞簡單的參數,比如查詢字符串。在 JSP 或者其他 Web 開發框架中,你可以直接在 URL 后面添加參數,然后在目標頁面獲取這些參數

地址重寫的格式如下:
????? 動態頁面地址?參數名稱1=參數內容1&參數名稱2=參數2&…

所有參數與之前的地址之間用“?”分離,然后按照“參數名稱=參數內容” 的格式傳遞參數,多個參數之間用“&”分離。

?假設你有一個動態頁面 dynamic_page.jsp,并且你想向其傳遞兩個參數:nameage。你可以像這樣構造 URL

http://yourwebsite.com/dynamic_page.jsp?name=John&age=30

在這個 URL 中,? 符號后面是參數部分,nameage 是參數名稱,而 John30 分別是對應的參數值。多個參數之間由 & 符號分隔

?在 dynamic_page.jsp 頁面中,你可以使用 request 對象的 getParameter() 方法來獲取這些參數

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>URL 重寫示例</title>
</head>
<body><%@ page import="java.util.Map.Entry" %><%-- 使用腳本元素 --%><%String name = request.getParameter("name");int age = Integer.parseInt(request.getParameter("age"));out.println("<p>姓名:" + name + "</p>");out.println("<p>年齡:" + age + "</p>");%>
</body>
</html>

在這個示例中,我們假設 age 參數是一個整數。如果你訪問上面提到的 URL,頁面將會顯示傳入的參數值。

表單

表單(Form)是網頁中用于收集用戶輸入信息的重要組成部分。在Web開發中,表單允許用戶輸入數據,然后將這些數據發送給服務器進行處理。HTML表單由各種表單控件組成,包括輸入字段(如文本框、密碼框)、按鈕、下拉列表、復選框、單選按鈕等。以下是一些關于HTML表單的關鍵概念和代碼示例:

表單標簽(<form>):表單的結構通常由<form>標簽開始,</form>標簽結束。<form>標簽有一些重要的屬性,包括:

  • action:定義處理表單數據的服務器端程序的URL。
  • method:定義如何將表單數據發送到服務器,通常是GETPOST
  • enctype:定義表單數據的編碼方式,主要在上傳文件時使用。

輸入控件(Input Controls):輸入控件用于捕獲用戶的輸入。常見的輸入控件有:

  • <input type="text">:文本輸入框。
  • <input type="password">:密碼輸入框。
  • <input type="radio">:單選按鈕。
  • <input type="checkbox">:復選框。
  • <select>:下拉列表。
  • <textarea>:多行文本輸入框。

按鈕(Buttons):按鈕用于觸發表單的提交或重置操作:

  • <input type="submit">:提交按鈕。
  • <input type="reset">:重置按鈕,清空表單數據。
  • <button>:通用按鈕,可以綁定JavaScript事件。

基本的HTML表單示例:

<!DOCTYPE html>
<html>
<head>
<title>簡單表單示例</title>
</head>
<body><form action="/submit_form" method="post">姓名:<input type="text" name="username"><br>密碼:<input type="password" name="password"><br>性別:<input type="radio" name="gender" value="male">男<input type="radio" name="gender" value="female">女<br>愛好:<input type="checkbox" name="hobbies" value="reading">閱讀<input type="checkbox" name="hobbies" value="music">音樂<input type="checkbox" name="hobbies" value="sports">運動<br>描述:<textarea name="description" rows="4" cols="50"></textarea><br><input type="submit" value="提交">
</form></body>
</html>

表單操作

<form> 標簽用于創建表單,其中最重要的屬性之一是 method 屬性,它決定了表單數據如何被發送到服務器。有兩種主要的提交方式:GETPOST

GET 方式

GET 提交方式會在 URL 后面附加一個問號(?),接著是鍵值對的形式,多個鍵值對之間用 & 分隔。這種提交方式適用于小型數據量的請求,而且在地址欄中可以看到所有提交的內容。

<form action="submit.php" method="get">姓名:<input type="text" name="username"><br>密碼:<input type="password" name="password"><br><input type="submit" value="提交">
</form>

當你提交此表單時,瀏覽器將在 URL 后面附加類似這樣的內容

http://yourwebsite.com/submit.php?username=John&password=123456

POST 方式

POST 提交方式不會在地址欄顯示提交的內容,而是將數據作為 HTTP 請求體的一部分發送到服務器。這種方式更適合大型數據量的請求,特別是包含敏感信息的場景。

<form action="submit.php" method="post">姓名:<input type="text" name="username"><br>密碼:<input type="password" name="password"><br><input type="submit" value="提交">
</form>

在這種情況下,提交后 URL 不會發生變化,但服務器可以通過 $_POST['username']$_POST['password'] 獲取相應的值。

GET 和 POST 的區別

  1. 數據可見性:GET 提交的內容會顯示在地址欄,而 POST 不會。
  2. 數據大小限制:GET 請求在地址欄上顯示的信息長度有限制(約 4~5KB),而 POST 可以提交更多的內容,如大文本和圖片數據。
  3. 安全性:POST 更加安全,因為它不會在地址欄顯示敏感信息。
  4. 緩存:GET 請求可以被緩存,而 POST 請求不能。
  5. 書簽:GET 請求可以保存為書簽,而 POST 請求不可以。

JSP 中的處理

在 JSP 中,你可以使用 request.getParameter() 方法來獲取表單數據。以下是一個簡單的示例,展示如何處理 GET 和 POST 請求

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>表單操作示例</title>
</head>
<body><%@ page import="java.util.Map.Entry" %><%-- 使用腳本元素 --%><%if ("POST".equals(request.getMethod())) {String username = request.getParameter("username");String password = request.getParameter("password");out.println("<p>姓名:" + username + "</p>");out.println("<p>密碼:" + password + "</p>");} else if ("GET".equals(request.getMethod())) {String username = request.getParameter("username");String password = request.getParameter("password");out.println("<p>姓名:" + username + "</p>");out.println("<p>密碼:" + password + "</p>");}%>
</body>
</html>

response對象

response 對象是 Java Servlet 技術中的一個重要對象,它代表了服務器對客戶端的響應。response 對象的主要作用是將服務器處理后的結果返回給客戶端。response 對象屬于 javax.servlet.http.HttpServletResponse 接口的實例,該接口繼承自 javax.servlet.ServletResponse 接口。

HttpServletResponse 接口定義了一些常用的方法

public interface HttpServletResponse extends ServletResponse {void addCookie(Cookie cookie);void sendRedirect(String location) throws IOException;void setHeader(String name, String value);void setDateHeader(String name, long date);void setContentType(String type);void setStatus(int sc);
}

public void addCookie(Cookie cookie)方法用于向客戶端發送 Cookie。

Cookie cookie = new Cookie("key", "value");
response.addCookie(cookie);

public void setHeader(String name,String value)方法用于設置響應頭,例如設置 Content-Type。

response.setContentType("text/html;charset=utf-8");

public void sendRedirect(String location) throws IOException方法用于重定向到另一個頁面。

response.sendRedirect("/new_location");

☆頁面跳轉

JSP中,我們可以通過兩種方式實現頁面跳轉:

一種是使用頭信息的方式完成跳轉

<%response.setHeader("Refresh", "2;URL=yourPage.jsp");
%>

我們在服務器端設置了一個響應頭"Refresh",其值為"2;URL=yourPage.jsp"。這意味著在兩秒后,瀏覽器將自動跳轉到yourPage.jsp頁面。?

另一種則是通過response對象的sendRedirect()方法直接完成頁面的跳轉(屬于客戶端跳轉)

<%response.sendRedirect("yourPage.jsp");
%>

我們調用了response對象的sendRedirect()方法,傳入了要跳轉的目標頁面地址。這個方法會向客戶端發送一個302臨時重定向響應,告訴客戶端需要跳轉到新的位置。

注意的是:這兩種跳轉方式有所不同。使用頭信息的方式屬于服務器端跳轉,而使用sendRedirect()方法則屬于客戶端跳轉。服務器端跳轉時,瀏覽器不會看到實際的URL變化,因為所有的處理都在服務器端完成;而在客戶端跳轉時,瀏覽器可以看到URL的變化,因為它實際上是重新發起了一個新的HTTP請求。

此外,客戶端跳轉的一個缺點是它可能會導致數據丟失。例如,在表單提交之后再進行客戶端跳轉,那么用戶輸入的數據將會丟失。因此,在某些情況下,可能更傾向于使用服務器端跳轉。

session對象

session對象是Java Web開發中的一個重要概念,主要用于管理用戶的會話狀態。在Web應用中,每個用戶訪問網站時都會產生一個唯一的session對象,用于存儲和獲取該用戶的相關信息。

在開發中,session對象最常見的用途就是完成用戶的登錄、注銷等常見功能。當用戶成功登錄后,我們可以把用戶的一些基本信息存放到session中,如用戶名、角色等。這樣,在后續的頁面訪問過程中,就可以通過檢查session中的這些信息來判斷當前用戶是否已經登錄以及他的權限等級等。

簡單的示例,演示了如何創建并使用session對象

import javax.servlet.http.HttpSession;// 在Servlet類中獲取session對象
HttpSession session = request.getSession();// 創建一個新的屬性并賦值給session
String username = "John Doe";
session.setAttribute("username", username);// 獲取之前設置的屬性
String retrievedUsername = (String) session.getAttribute("username");// 輸出結果
System.out.println("Retrieved username from session: " + retrievedUsername);

首先從HttpServletRequest對象中獲取到了一個session對象。然后,我們將字符串"John Doe"保存到了session對象中,鍵為"username"。最后,我們又從session中取出了之前設置的屬性,并打印出來。

?取得Session Id

ession是一種用來跟蹤用戶狀態的技術。當一個用戶連接到服務器之后,服務器會為其分配一個唯一的Session Id,這個Id通常是一串隨機生成的字符串。服務器依靠這些不同的Session Id來區分每一個不同的用戶。

Session Id通常是通過cookie存儲在客戶端的,每次客戶端發起請求的時候,都會帶上這個Session Id,服務器通過解析這個Id來識別用戶的身份。

如何獲取Session Id

import javax.servlet.http.HttpSession;public class SessionIdExample {public void getSessionId(HttpSession session) {String sessionId = session.getId();System.out.println("Session Id is: " + sessionId);}
}

首先從HttpServletRequest對象中獲取到了一個session對象,然后調用getId()方法獲取Session Id,并將其打印出來。

注意:?

Session Id是由服務器自動生成的,開發者不能手動修改。而且,一旦Session被創建,它的Id就不會改變,除非Session過期或者被顯式地銷毀。

另外,雖然Session Id是通過cookie傳遞的,但是如果你的應用需要支持那些不支持cookie的瀏覽器,你也可以選擇通過URL重寫的方式來傳遞Session Id。這種方式下,服務器會在URL后面添加一個參數,用來攜帶Session Id。

處理數據

session對象提供了兩個主要的方法來處理數據:setAttribute(String key, Object obj) 和 getAttribute(String key)。

1.setAttribute(String key, Object obj): 這個方法用于將指定的對象obj添加到session對象中,并為添加的對象指定一個索引關鍵字key。如果添加的兩個對象的關鍵字相同,則先前添加的對象會被清除。這是一個非常有用的功能,因為我們經常需要在用戶會話期間存儲一些數據,比如用戶ID、購物車信息等等

HttpSession session = request.getSession();
session.setAttribute("userId", 123); // 將用戶ID存儲在session中

2.getAttribute(String key): 這個方法用于獲取session對象含有的關鍵字是key的對象。由于任何對象都可以添加到session對象中,因此用該方法取回對象時,應強制轉化為原來的類型。

HttpSession session = request.getSession();
int userId = (Integer) session.getAttribute("userId"); // 取出用戶ID

注意,當我們使用getAttributes()方法取出對象時,我們需要進行類型轉換,這是因為getAttribute()返回的是Object類型的對象,所以我們需要將其轉換為我們期望的類型。

☆“登陸及注銷”模塊

?session對象常常被用來實現用戶登陸及注銷的功能。具體來說,當用戶成功登陸后,我們會將一些關鍵信息(如用戶名、用戶ID等)存儲在session中,以便在后續的請求中驗證用戶身份。同時,我們還可以提供一個注銷功能,讓用戶能夠結束自己的會話。

實現:

? 當用戶登陸成功之后,設置一個 session 范圍的屬性,之后在其他需要驗證的頁面中判斷是否存在此 session 范圍的屬性
1 如果存在 ,則表示已經是正常登陸過的合法用戶, 2 如果不存在 ,則給出提示,并跳轉回登陸頁提示用戶重新登陸,用戶登陸之后可以進行注銷的操作。
  1. 登陸頁login.jsp
    <form action="LoginServlet" method="post">用戶名:<input type="text" name="username"><br>密碼:<input type="password" name="password"><br><input type="submit" value="登陸">
    </form>
  2. LoginServlet.java
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;@WebServlet("/LoginServlet")
    public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");if (checkUser(username, password)) { // 檢查用戶是否存在HttpSession session = request.getSession();session.setAttribute("currentUser", username); // 存儲用戶信息到sessionresponse.sendRedirect("welcome.jsp"); // 跳轉到歡迎頁面} else {request.getRequestDispatcher("login.jsp").forward(request, response); // 如果用戶不存在,繼續停留在登陸頁面}}private boolean checkUser(String username, String password) {// 假設這里是對數據庫的查詢,判斷用戶是否存在return true;}
    }

?????????3.welcome.jsp

<%@ page import="javax.servlet.http.HttpSession" %>
<%HttpSession session = request.getSession();String currentUser = (String) session.getAttribute("currentUser");if (currentUser == null) {response.sendRedirect("login.jsp"); // 如果session中沒有用戶信息,表示未登陸,跳轉到登陸頁面}
%>
<h1>歡迎 <%= currentUser %>!</h1>
<a href="LogoutServlet">注銷</a>

? ? ? ? ?4.LogoutServlet.java

import javax.servlet.http.HttpSession;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpSession session = request.getSession();session.invalidate(); // 注銷sessionresponse.sendRedirect("login.jsp"); // 跳轉到登陸頁面}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/41922.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/41922.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/41922.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Docker在人工智能領域的應用與實戰

摘要 人工智能&#xff08;AI&#xff09;技術的快速發展帶來了對高效開發和部署工具的需求。Docker作為一個創新的容器化平臺&#xff0c;為AI領域提供了強大的支持。本文詳細介紹了Docker在AI模型開發、訓練、部署以及服務器集群管理等方面的應用&#xff0c;并探討了其在數…

AcWing 1550:完全二叉搜索樹

【題目來源】https://www.acwing.com/problem/content/1552/【題目描述】二叉搜索樹 (BST) 遞歸定義為具有以下屬性的二叉樹&#xff1a; &#xff08;1&#xff09;若它的左子樹不空&#xff0c;則左子樹上所有結點的值均小于它的根結點的值 &#xff08;2&#xff09;若它的右…

大數據平臺之數據同步

數據同步也成為CDC (Chanage Data Capture) 。Change Data Capture (CDC) 是一種用于跟蹤和捕獲數據庫中數據變更的技術&#xff0c;它可以在數據發生變化時實時地將這些變更捕獲并傳遞到下游系統。以下是一些常用的開源 CDC 方案&#xff1a; 1. Flink CDC Flink CDC 是基于 …

快速上手LangChain:構建強大的語言模型應用

引言 在人工智能和自然語言處理&#xff08;NLP&#xff09;領域&#xff0c;構建高效且強大的語言模型應用變得越來越重要。LangChain 是一個專為開發者設計的框架&#xff0c;它簡化了語言模型應用的構建流程。本文將詳細介紹LangChain的功能和使用方法&#xff0c;幫助讀者…

76 4G模組 境外撥號入網注意

1 引言 最近朋友把國內的設備拿到新加坡了&#xff0c;然后發現原本國內可以使用的設備無法在異國他鄉聯網&#xff0c;所以就叫我來看看&#xff0c;發現是附網返回狀態、入網APN發生了改變導致的。另外&#xff0c;如果在境外使用國產4G模組撥號入網&#xff0c;也需要關注4G…

Windows安裝超好用的截圖工具——Snipaste

1、下載 官網&#xff1a;https://zh.snipaste.com/ 2、安裝 &#xff08;1&#xff09;解壓下載的壓縮包 &#xff08;2&#xff09;選中Snipaste.exe文件&#xff0c;右鍵發送到 -- > 桌面快捷方式 &#xff08;3&#xff09;雙擊桌面Snipaste圖標&#xff0c;桌面右下…

linux 服務器數據備份 和 mysql 數據遷移

查看域名ip 查看程序所處文件位置 list open files 1、 lsof -i :port 查看端口獲取進程 pid 2、lsof -i pid 1、scp 下載服務器文件到本地 security copy protocol 2、導出服務器 mysql 數據庫&#xff08;表&#xff09;到本地 mysqldump是MySQL自帶的一個實用程序&…

解析Java中1000個常用類:Date類,你學會了嗎?

在線工具站 推薦一個程序員在線工具站:程序員常用工具(http://cxytools.com),有時間戳、JSON格式化、文本對比、HASH生成、UUID生成等常用工具,效率加倍嘎嘎好用。程序員資料站 推薦一個程序員編程資料站:程序員的成長之路(http://cxyroad.com),收錄了一些列的技術教程…

Git 完整的提交規范教程

約定式提交規范 本文中的關鍵詞 “必須&#xff08;MUST&#xff09;”、“禁止&#xff08;MUST NOT&#xff09;”、“必要&#xff08;REQUIRED&#xff09;”、“應當&#xff08;SHALL&#xff09;”、“不應當&#xff08;SHALL NOT&#xff09;”、“應該&#xff08;S…

云計算【第一階段(24)】Linux文件系統與日志分析

一、文件與存儲系統的inode與block 1.1、硬盤存儲 最小存儲單位&#xff1a;扇區(sector) 每個扇區大小&#xff1a;512字節 1.2、文件存取 最小存取單位&#xff1a;塊(block)連續八個扇區組成&#xff1a;塊(block) 每個塊大小&#xff1a;4K文件數據&#xff1a;實際數據…

Leetcode1115 交替打印 FooBar及其測試

題目描述 相關標簽 相關企業 給你一個類&#xff1a; class FooBar { public void foo() { for (int i 0; i < n; i) { print(“foo”); } } public void bar() { for (int i 0; i < n; i) { print(“bar”); } } } 兩個不同的線程將會共用一個 FooBar 實例&#xf…

Java面試八股之如何提高MySQL的insert性能

如何提高MySQL的insert性能 提高MySQL的INSERT性能可以通過多種策略實現&#xff0c;以下是一些常見的優化技巧&#xff1a; 批量插入&#xff1a; 而不是逐條插入&#xff0c;可以使用單個INSERT語句插入多行數據。例如&#xff1a; INSERT INTO table_name (col1, col2) V…

正則表達式-使用筆記

正則表達式使用不當&#xff0c;會導致CPU飆升&#xff1b; 二、相關參考 正則表達式 – 語法 | 菜鳥教程 sparksql 正則匹配總結 三、回溯原理 導致性能下降最主要原因&#xff1a; .* 會導致大量回溯| 分支操作 https://zhuanlan.zhihu.com/p/27417442 四、常用工具 regex…

OpenSNN推文:科技前沿動態速覽:六七月份的技術革新與行業進展

隨著夏季的到來&#xff0c;科技界的熱度也如同氣溫一般持續攀升。在這個充滿活力的季節里&#xff0c;從量子計算的深邃世界到腦機接口的未來探索&#xff0c;從人工智能的智慧躍升到大數據的海洋遨游&#xff0c;再到運營策略的精妙布局和設計領域的創新火花&#xff0c;以及…

2024第三屆中國醫療機器人大會第一輪通知

2024第三屆中國醫療機器人大會第一輪通知 大會背景 醫療機器人技術正以前所未有的速度在主流醫學領域取得卓越進展&#xff0c;新應用、新技術不斷涌現&#xff0c;使得該領域在過去一年中取得了令人驚嘆的增長。然而&#xff0c;這僅僅是冰山一角&#xff0c;未來的發展空間仍…

Docker:一、安裝與卸載、配置阿里云加速器(Ubuntu)

目錄 &#x1f341;安裝docker&#x1f332;1、環境準備&#x1f332;2、安裝docker Engine&#x1f9ca;1、卸載舊版、任何沖突的包&#x1f9ca;2、使用存儲庫安裝&#x1f9ca;3、安裝 Docker 包。&#x1f9ca;4、查詢是否安裝成功&#x1f9ca;5、運行hello-world鏡像&…

柯橋小語種學校成人生活口語學習|西班牙語中H為什么不發音…

01 H en el alfabeto espaol 西語字母表中的h 字母H是唯一一個在標準西班牙語中不再代表任何音素的字母。盡管在它單獨出現時被叫做HACHE&#xff0c;但在大多數單詞拼寫中&#xff0c;它只是一個沒有聲音對應關系的字母&#xff0c;因此RAE稱其為“無聲的H”&#xff08;hac…

機器學習——無監督學習(k-means算法)

1、K-Means聚類算法 K表示超參數個數&#xff0c;如分成幾個類別&#xff0c;K值就取多少。若無需求&#xff0c;可使用網格搜索找到最佳的K。 步驟&#xff1a; 1、隨機設置K個特征空間內的點作為初始聚類中心&#xff1b; 2、對于其他每個點計算到K個中心的距離&#xff0c;…

蕎面打造的甜蜜魔法:甜甜圈

食家巷蕎面甜甜圈是一款具有特色的美食。它以蕎面為主要原料&#xff0c;相較于普通面粉&#xff0c;蕎面具有更高的營養價值&#xff0c;富含膳食纖維、維生素和礦物質。蕎面甜甜圈的口感可能會更加扎實和有嚼勁&#xff0c;同時帶著蕎面特有的谷物香氣。在制作過程中&#xf…

FlutterWeb渲染模式及提速

背景 在使用Flutter Web開發的網站過程中&#xff0c;常常會遇到不同瀏覽器之間的兼容性問題。例如&#xff0c;在Google瀏覽器中動畫和交互都非常流暢&#xff0c;但在360瀏覽器中卻會出現卡頓現象&#xff1b;在Google瀏覽器中動態設置圖標顏色正常顯示&#xff0c;而在Safa…