轉發和重定向的區別詳解

轉發(Forward)和重定向(Redirect)是 Web 開發中兩種常用的請求處理方式,主要用于將客戶端請求從一個資源轉移到另一個資源。它們在實現機制、行為表現和應用場景上有顯著區別,以下是對兩者的詳細解析:


一、轉發(Forward)

1.定義

  • 轉發是服務器內部的行為,由服務器直接將請求從一個資源(如 Servlet、JSP)傳遞到另一個資源,客戶端(瀏覽器)對此過程無感知。

  • 地址欄不變用戶看到的 URL 是初始請求的地址,而非最終處理請求的資源地址。

2.工作原理

  1. 客戶端發送請求到服務器。

  2. 服務器通過?RequestDispatcher?將請求轉發到目標資源。

  3. 目標資源處理請求并生成響應。

  4. 服務器將響應返回給客戶端。

3.特點

  • 一次請求:客戶端僅發起一次請求,服務器內部完成轉發。

  • 數據共享:通過?request.setAttribute()?傳遞數據,目標資源可直接使用。

  • 路徑限制:只能轉發到同一 Web 應用內的資源。

  • 性能高效:無需額外網絡交互。

4.語法

// 在 Servlet 中實現轉發
RequestDispatcher dispatcher = request.getRequestDispatcher("/target.jsp");
request.setAttribute("message", "Hello from Forward");
dispatcher.forward(request, response);

5.示例代碼驗證:

User類

 * 3. 一個JavaBean一般是有規范的:*      有無參數的構造方法*      屬性私有化*      對外提供setter和getter方法*      重寫toString()*      重寫hashCode + equals*      實現java.io.Serializable接口。*/
public class User implements Serializable {private String id;private String name;public User() {}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return Objects.equals(id, user.id) && Objects.equals(name, user.name);}@Overridepublic int hashCode() {return Objects.hash(id, name);}@Overridepublic String toString() {return "User{" +"id='" + id + '\'' +", name='" + name + '\'' +'}';}public User(String id, String name) {this.id = id;this.name = name;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

AServlet類

package oop1.servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import oop1.bean.User;import java.io.IOException;public class AServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 創建一個用戶對象User user = new User();user.setId("111111");user.setName("杰克");// 將用戶對象存儲到請求域當中request.setAttribute("userObj", user);// 轉發request.getRequestDispatcher("/b").forward(request, response);}
}

BServlet類

package oop1.servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;
import java.io.PrintWriter;public class BServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 從請求域當中取出存儲的數據Object userObj = request.getAttribute("userObj");// 輸出到瀏覽器response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.print("請求域當中的用戶對象:" + userObj);}
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>a</servlet-name><servlet-class>oop1.servlet.AServlet</servlet-class></servlet><servlet-mapping><servlet-name>a</servlet-name><url-pattern>/a</url-pattern></servlet-mapping><servlet><servlet-name>b</servlet-name><servlet-class>oop1.servlet.BServlet</servlet-class></servlet><servlet-mapping><servlet-name>b</servlet-name><url-pattern>/b</url-pattern></servlet-mapping></web-app>

運行結果:

二、重定向(Redirect)

1.定義

  • 重定向是客戶端行為,服務器返回一個特殊響應(狀態碼 302 或 307),指示客戶端重新發起對新 URL 的請求。

  • 地址欄變化:用戶最終看到的是新請求的 URL。

2.工作原理

  1. 客戶端發送請求到服務器。

  2. 服務器返回狀態碼 302 和?Location?頭(新 URL)。

  3. 客戶端自動向新 URL 發起第二次請求。

  4. 新資源處理請求并返回響應。

3.特點

  • 兩次請求:客戶端發起兩次獨立的請求。

  • 數據隔離:兩次請求的?request?對象不同,需通過 URL 參數、Session 或 Cookie 傳遞數據。

  • 路徑靈活:可重定向到任意 URL(包括外部域名)。

  • 性能開銷:多一次網絡往返,效率略低。

4.語法:

// 在 Servlet 中實現重定向
response.sendRedirect("http://example.com/newPage.jsp");
// 通過 URL 參數傳遞數據
response.sendRedirect("/newPage.jsp?message=Hello+from+Redirect");

5.示例代碼驗證

僅修改AServlet類

?// 重定向(重新定方向)


? ? ? ? // 重定向時的路徑當中需要以項目名開始,或者說需要添加項目名。
? ? ? ? // response對象將這個路徑:"/servlet10/b"響應給瀏覽器了。
? ? ? ? // 瀏覽器又自發的向服務器發送了一次全新的請求:http://localhost:8080/servlet10/b
? ? ? ? // 所以瀏覽器一共發送了兩次請求:
? ? ? ? // 第一次請求:http://localhost:8080/servlet10/a
? ? ? ? // 第二次請求:http://localhost:8080/servlet10/b
? ? ? ? // 最終瀏覽器地址欄上顯示的地址當然是最后那一次請求的地址。所以重定向會導致瀏覽器地址欄上的地址發生改變。

package oop1.servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import oop1.bean.User;import java.io.IOException;public class AServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 創建一個用戶對象User user = new User();user.setId("111111");user.setName("杰克");// 將用戶對象存儲到請求域當中request.setAttribute("userObj", user);// 重定向(重新定方向)// 重定向時的路徑當中需要以項目名開始,或者說需要添加項目名。// response對象將這個路徑:"/servlet10/b"響應給瀏覽器了。// 瀏覽器又自發的向服務器發送了一次全新的請求:http://localhost:8080/servlet10/b// 所以瀏覽器一共發送了兩次請求:// 第一次請求:http://localhost:8080/servlet10/a// 第二次請求:http://localhost:8080/servlet10/b// 最終瀏覽器地址欄上顯示的地址當然是最后那一次請求的地址。所以重定向會導致瀏覽器地址欄上的地址發生改變。response.sendRedirect(request.getContextPath() + "/b");}
}

運行結果:

三、轉發和重定向有什么區別?

1.形式上有什么區別?

  • 轉發(一次請求)

    • 在瀏覽器地址欄上發送的請求是:http://localhost:8080/servlet10/a ,最終請求結束之后,瀏覽器地址欄上的地址還是這個。沒變。

  • 重定向(兩次請求)

    • 在瀏覽器地址欄上發送的請求是:http://localhost:8080/servlet10/a ,最終在瀏覽器地址欄上顯示的地址是:http://localhost:8080/servlet10/b

2.轉發和重定向的本質區別?

  • 轉發:是由WEB服務器來控制的。A資源跳轉到B資源,這個跳轉動作是Tomcat服務器內部完成的。

  • 重定向:是瀏覽器完成的。具體跳轉到哪個資源,是瀏覽器說了算。

3.轉發和重定向應該如何選擇?什么時候使用轉發,什么時候使用重定向?

  • 如果在上一個Servlet當中向request域當中綁定了數據,希望從下一個Servlet當中把request域里面的數據取出來,使用轉發機制。

  • 剩下所有的請求均使用重定向。(重定向使用較多。)

四、核心區別對比

特性轉發(Forward)重定向(Redirect)
請求次數一次請求,服務器內部處理兩次獨立請求
地址欄變化不變化(顯示初始 URL)變化(顯示最終 URL)
數據共享通過?request?作用域傳遞需手動傳遞(URL、Session 等)
路徑范圍僅限同一應用內可跨應用、跨域
性能高效(無額外網絡交互)較低(多一次往返)
實現方式RequestDispatcher.forward()response.sendRedirect()
HTTP 狀態碼無明確狀態碼(服務器內部處理)302(臨時)或 307(永久重定向)

五、使用場景

適合轉發的場景
  1. 隱藏實現細節:例如表單提交后跳轉到結果頁,但保持 URL 不變。

  2. 共享請求數據:在多個服務器端資源間傳遞數據(如 Servlet → JSP)。

  3. 避免重復提交:處理 POST 請求后轉發到結果頁,防止用戶刷新導致重復提交。

適合重定向的場景
  1. 跨應用跳轉:例如從舊系統跳轉到新系統的頁面。

  2. 防止重復提交:處理 POST 請求后重定向到 GET 請求(如 PRG 模式,Post-Redirect-Get)。

  3. 用戶登錄/注銷:登錄后重定向到主頁,避免刷新時重復提交表單。

  4. 依賴外部資源:例如調用第三方支付接口后重定向回本站。


六、進階補充

  1. PRG 模式
    通過重定向解決表單重復提交問題:用戶提交表單(POST)→ 服務器處理并重定向到結果頁(GET)→ 用戶刷新不會重復提交數據。

  2. 框架中的使用

    • Spring MVC

      • 轉發:return "forward:/target"

      • 重定向:return "redirect:/target"

    • Thymeleaf/JSP:直接通過視圖解析器處理轉發邏輯。


七、總結

  • 轉發:服務器內部跳轉,高效但路徑受限,適合隱藏實現細節或共享數據。

  • 重定向:客戶端跳轉,靈活但性能略低,適合跨應用、防重復提交或依賴外部資源。

根據具體需求選擇合適的方式,例如對安全性和路徑有要求時用轉發,需要跨域或避免重復提交時用重定向。

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

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

相關文章

python專題1-----判斷一個變量是否是字符串類型

在 Python 中&#xff0c;可以使用 isinstance() 函數來判斷一個變量是否是字符串類型。字符串在 Python 中是以 str 類型表示的。下面是一些示例代碼&#xff0c;展示如何判斷一個變量是否是字符串類型&#xff1a; # 示例變量 var1 "Hello, World!" var2 12345 …

軟件工程之需求工程(需求獲取、分析、驗證)

一、需求獲取&#xff08;Requirements Elicitation&#xff09; 1. 定義與目標 需求獲取是通過與用戶、利益相關者等交互&#xff0c;識別并捕獲系統需求的過程&#xff0c;目標是明確用戶意圖與業務目標&#xff0c;避免后期因需求偏差導致返工。 2. 主要方法 問卷法&…

Java簡單生成pdf

生成這樣的PDF 直接上代碼 public static void main(String[] args) {String logoPath "Q:\\IdeaWork\\Demo\\src\\main\\webapp\\images\\logo.jpg"; // 替換為實際路徑String baseDir "E:/Demo/TEST/problem/Generate"; // 基礎目錄int year 2025; //…

k8s存儲介紹(六)StorangeClass

一、Kubernetes 存儲類&#xff08;StorageClass&#xff09;詳解 1. 什么是 StorageClass&#xff1f; 在 Kubernetes 中&#xff0c;StorageClass&#xff08;存儲類&#xff09;是一種用于動態創建 PersistentVolume&#xff08;PV&#xff09;的資源對象。它允許管理員根…

C++:allocator類(動態數組續)

1.為什么需要 allocator&#xff1f; 在 C 中&#xff0c;動態內存管理通常通過 new 和 delete 完成&#xff1a; int* p new int; // 分配內存 構造對象 delete p; // 析構對象 釋放內存 但 new 和 delete 有兩個問題&#xff1a; 耦合性&#xff1a;將內…

北斗導航 | 中國北斗衛星導航系統的發展歷程——“三步走”戰略:背景,信號頻點,調制方式,短報文,等

中國北斗衛星導航系統的發展歷程按照“三步走”戰略逐步推進,從區域服務到全球覆蓋,形成了北斗一號、北斗二號、北斗三號三代系統的迭代升級,展現了中國航天科技的自主創新與突破。以下是各階段的核心內容與發展特點綜述:一、北斗一號:中國衛星導航的奠基(1994-2003年) …

Headless Chrome 優化:減少內存占用與提速技巧

在當今數據驅動的時代&#xff0c;爬蟲技術在各行各業扮演著重要角色。傳統的爬蟲方法往往因為界面渲染和資源消耗過高而無法滿足大規模數據采集的需求。本文將深度剖析 Headless Chrome 的優化方案&#xff0c;重點探討如何利用代理 IP、Cookie 和 User-Agent 設置實現內存占用…

英偉達GB300新寵:新型LPDDR5X SOCAMM內存

隨著人工智能&#xff08;AI&#xff09;、機器學習&#xff08;ML&#xff09;和高性能計算&#xff08;HPC&#xff09;應用的快速發展&#xff0c;對于高效能、大容量且低延遲內存的需求日益增長。NVIDIA在其GB系列GPU中引入了不同的內存模塊設計&#xff0c;以滿足這些嚴格…

靜態網頁應用開發環境搭建實戰教程

1. 前言 靜態網頁開發是前端工程師的基礎技能之一&#xff0c;無論是個人博客、企業官網還是簡單的Web應用&#xff0c;都離不開HTML、CSS和JavaScript。搭建一個高效的開發環境&#xff0c;能夠極大提升開發效率&#xff0c;減少重復工作&#xff0c;并優化調試體驗。 本教程…

Python每日一題(9)

Python每日一題 2025.3.29 一、題目二、分析三、源代碼四、deepseek答案五、源代碼與ai分析 一、題目 question["""企業發放的獎金根據利潤提成。利潤(I)低于或等于10萬元時,獎金可提10%,利潤高于10萬元,低于20萬元時,低于10萬元的部分按10%提成,高于10萬元的部…

游戲引擎學習第187天

看起來觀眾解決了上次的bug 昨天遇到了一個相對困難的bug&#xff0c;可以說它相當棘手。剛開始的時候&#xff0c;沒有立刻想到什么合適的解決辦法&#xff0c;所以今天得從頭開始&#xff0c;逐步驗證之前的假設&#xff0c;收集足夠的信息&#xff0c;逐一排查可能的原因&a…

【入門初級篇】布局類組件的使用(1)

【入門初級篇】布局類組件的使用&#xff08;1&#xff09; 視頻要點 &#xff08;1&#xff09;章節大綱介紹 &#xff08;2&#xff09;布局類組件類型介紹&#xff1a;行布局、列布局、標題 &#xff08;3&#xff09;實操演示&#xff1a;列表統計查詢布局模型 點擊訪問my…

對內核fork進程中寫時復制的理解記錄

前言 文章寫于學習Redis時對aof后臺重寫中寫時復制的疑問 一、感到不理解的歧義 在部分技術文檔中&#xff08;以小林的文章為例&#xff09;&#xff0c;對寫時復制后的內存權限存在如歧義&#xff1a; ! 二、正確技術表述 根據Linux內核實現&#xff08;5.15版本&#x…

Ditto-Talkinghead:阿里巴巴數字人技術新突破 [特殊字符]?

Ditto-Talkinghead&#xff1a;阿里巴巴數字人技術新突破 &#x1f5e3;? 阿里巴巴推出了一項新的數字人技術&#xff0c;名為 Ditto-Talkinghead。這項技術主要用于生成由音頻驅動的說話頭&#xff0c;也就是我們常說的“數字人”。不過&#xff0c;現有的基于擴散模型的同類…

.NET開發基礎知識1-10

1. 依賴注入&#xff08;Dependency Injection&#xff09; 技術知識&#xff1a;依賴注入是一種設計模式&#xff0c;它允許將對象的依賴關系從對象本身中分離出來&#xff0c;通過構造函數、屬性或方法參數等方式注入到對象中。這樣可以提高代碼的可測試性、可維護性和可擴展…

每日一題 MySQL基礎知識----(三)

數據庫常用基礎知識&#xff1a;代碼講解和實驗 1.創建數據庫student 02&#xff0c;創建一個名為student02的數據庫 CREATE DATABASE student02; 2.在student02中創建一張 students表&#xff0c;并且具有學生的編號id&#xff0c;姓名name&#xff0c;年齡age&#xff0c;生…

MySQL多表查詢實驗

1.數據準備 -- 以下語句用于創建 students 表&#xff0c;該表存儲學生的基本信息 -- 定義表名為 students CREATE TABLE students (-- 定義學生的唯一標識符&#xff0c;類型為整數&#xff0c;作為主鍵&#xff0c;且支持自動遞增student_id INT PRIMARY KEY AUTO_INCREMENT…

windows第二十章 單文檔應用程序

文章目錄 單文檔定義新建一個單文檔應用程序單文檔應用程序組成&#xff1a;APP應用程序類框架類&#xff08;窗口類&#xff09;視圖類&#xff08;窗口類&#xff0c;屬于框架的子窗口&#xff09;文檔類&#xff08;對數據進行保存讀取操作&#xff09; 直接用向導創建單文檔…

C++ 初階總復習 (16~30)

C 初階總復習 &#xff08;16~30&#xff09; 目的16. 2009. volatile關鍵字的作用17. 2010.什么是多態 簡單介紹下C的多態18. 2011. 什么是虛函數 介紹下C中虛函數的原理19. 2012 構造函數可以是虛函數嘛20. 2013.析構函數一定要是虛函數嘛&#xff1f;21. 2015. 什么是C中的虛…

第一天 Linux驅動程序簡介

目錄 一、驅動的作用 二、裸機驅動 VS linux驅動 1、裸機驅動 2、linux驅動 三、linux驅動位于哪里&#xff1f; 四、應用編程 VS 內核編程 1、共同點 2、不同點 五、linux驅動分類 1、字符設備 2、塊設備 3、網絡設備 六、Linux驅動學習難點與誤區 1、學習難點 …