一、先搞懂核心区别(避免用错)
请求转发和重定向都是页面跳转,但底层逻辑完全不同,先记住关键差异:
| 特性 | 请求转发(Forward) | 重定向(Redirect) |
|---|---|---|
| 核心原理 | 服务器内部跳转,一次请求 | 服务器告诉浏览器跳新地址,两次请求 |
| URL 地址栏 | 不变(显示原请求地址) | 变化(显示新地址) |
| 数据共享 | 可通过 request 共享数据 | 不可共享(两次请求,request 不同) |
| 跳转范围 | 仅能跳当前 Web 应用内的资源 | 可跳任意地址(外部网站也可以) |
| 代码关键字 | request.getRequestDispatcher().forward() |
response.sendRedirect() |
二、请求转发(Forward):服务器内部跳转
1. 适用场景
- 处理完业务逻辑后,跳转到页面展示结果(如登录成功跳首页);
- 需要在跳转后传递数据(如查询结果、提示信息)。
2. 核心代码
java
运行
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/forwardDemo")
public class ForwardServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 1. 业务逻辑处理(示例:模拟查询用户信息)
String username = "张三";
int age = 25;
// 2. 往request中存数据(跳转后可获取)
req.setAttribute("username", username);
req.setAttribute("age", age);
try {
// 3. 请求转发到目标页面/Servlet(路径为当前应用内的相对路径)
// 跳转到index.jsp页面
req.getRequestDispatcher("/index.jsp").forward(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3. 接收转发数据(index.jsp 示例)
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<h1>欢迎你:${username}</h1>
<p>你的年龄:${age}</p>
</body>
</html>
三、重定向(Redirect):浏览器跳转新地址
1. 适用场景
- 登录 / 注册成功后跳转(避免刷新页面重复提交);
- 跳转到外部网站(如跳转到百度);
- 不需要传递 request 数据的跳转。
2. 核心代码
场景 1:跳转到当前应用内的资源
java
运行
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/redirectDemo1")
public class RedirectServlet1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 1. 模拟登录成功逻辑
String username = req.getParameter("username");
// 登录成功,重定向到首页(地址栏会变成/index.jsp)
resp.sendRedirect("/index.jsp");
}
}
场景 2:跳转到外部网站
java
运行
@WebServlet("/redirectDemo2")
public class RedirectServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 重定向到百度(外部地址)
resp.sendRedirect("https://www.baidu.com");
}
}
3. 重定向传递数据(补充)
重定向无法通过 request 传数据,可通过 URL 参数或 Session 传递:
java
运行
// 方式1:URL参数传递(适合简单数据)
resp.sendRedirect("/index.jsp?username=" + username);
// 方式2:Session传递(适合敏感/复杂数据)
req.getSession().setAttribute("username", username);
resp.sendRedirect("/index.jsp");
四、新手避坑点
-
路径问题 :
- 转发:用「相对路径」(相对于当前应用根目录,如
/index.jsp); - 重定向:如果跳应用内资源,路径要加应用上下文(或直接用
/xxx,Tomcat 会自动拼接);
- 转发:用「相对路径」(相对于当前应用根目录,如
-
转发后不能再操作响应 :
forward()后如果再调用resp.getWriter()会报错; -
中文乱码 :重定向 URL 传中文时,需编码:
java
运行
String encodeName = java.net.URLEncoder.encode("张三", "UTF-8"); resp.sendRedirect("/index.jsp?username=" + encodeName);
总结
关键点回顾
- 请求转发:服务器内部跳转,一次请求、URL 不变、可传 request 数据,适合应用内跳转且需要传数据的场景;
- 重定向:浏览器跳转,两次请求、URL 变化、不可传 request 数据,适合登录 / 注册后跳转或外部地址跳转;
- 核心口诀:「转发用 request,重定向用 response;转发地址不变,重定向地址变」。