转发和重定向的区别!

不要仅仅为了把变量传到下一个页面而使用session作用域,那会无故增大变量的作用域,转发也许可以帮助你解决这个问题。
重定向:以前的request中存放的变量全部失效,并进入一个新的request作用域。
转发:以前的request中存放的变量不会失效,就像把两个页面拼到了一起。

正文开始:

先是看上去不同,他们的调用分别如下:
request.getRequestDispatcher("apage.jsp").forward(request, response);//转发到apage.jsp
response.sendRedirect("apage.jsp");//重定向到apage.jsp
在jsp页面中你也会看到通过下面的方式实现转发:
<jsp:forward page="apage.jsp" />
我在初学jsp的时候,对这两个概念非常模糊,看别人的例子的时候,也是一头雾水,不知道什么时候该用哪个。希望下面的解说能对你有所帮

助。
提到转发和重定向就不得不提到request作用域。很多初学者都知道当我们提交一个表单时,就创建了一个新的请求。实际上,当我们点击一个

链接时,也创建了一个新的请求。那么一个请求的作用于到底有多大呢?例如:
在页面a.jsp中有一个链接<a href="b.jsp?id=1">这是指向b的一个链接,而且还带了一个参数</a>。当我们点击这个连接的时候,就产生了一

个请求,为了明确起见,我们把它叫做requestA->B。现在,在b.jsp页面中我们就可以从这个请求中获取信息了。在b.jsp中你可以写入out.pr

intln(request.getParameter("id"))进行测试。下面更复杂一点,我们在b.jsp页面中增加下面的语句:
request.setAttribute("name","funcreal");
out.println(request.getAttriblute("name"));//成功显示了name变量的值。
现在在b.jsp中再增加一个链接:<a href="c.jsp?age=23">这是指向c的一个链接,而且还带了一个参数</a>,当我们点击这个连接的时候,将

产生一个新的请求,这时requestA-B也就安息了,新的请求叫做requestB-C。同样的道理,在c.jsp中,我们可以访问到的变量只有age,因为i

d,name这两个变量都属于requestA-B,此时他已经不存在了。下面是源代码:
a.jsp
<%@ page contentType="text/html; charset=GBK" %>
<html>
<body bgcolor="#ffffff">
<a href="b.jsp?id=1">指向b.jsp,而且还带了一个参数id=1。requestA-B现在诞生了</a>
</body>
</html>

b.jsp
<%@ page contentType="text/html; charset=GBK" %>
<html>
<body bgcolor="#ffffff">
<%
out.println("id=" + request.getParameter("id"));
request.setAttribute("name","Func Real");
out.println("name=" + request.getAttribute("name"));
%>
<a href="c.jsp?age=23">requestA-B已经结束了。指向c.jsp,而且还带了一个参数age=23</a>
</body>
</html>

c.jsp
<%@ page contentType="text/html; charset=GBK" %>
<html>
<body bgcolor="#ffffff">
<%
out.println("id=" + request.getParameter("id"));
out.println("name=" + request.getAttribute("name"));
out.println("age=" + request.getParameter("age"));
%>
</body>
</html>

那么转发又是怎么回事呢?现在增加一个页面叫做d.jsp,并且在c.jsp中</body>前面增加一句<jsp:forward page="d.jsp"/>
d.jsp
<%@ page contentType="text/html; charset=GBK" %>
<html>
<body bgcolor="#ffffff">
requestB-C的魔爪已经伸到了d.jsp页面
<%
out.println("age=" + request.getParameter("age"));
%>
</body>
</html>
运行程序,你会发现c页面中的内容没有显示出来,因为forward是自动执行的,地址栏中虽然是c.jsp但实际上,但浏览器中显示的已经是d.js

p的内容了,而且看到了从b.jsp传过来的参数。你可以简单得这样理解:转发,就是延长了requestB-C的作用域,<jsp:forward

page="d.jsp"/>,这一句话实际上是把c.jsp和d.jsp粘到了一起,他们就像是在一个页面中。
如果你用过struts,那么你就知道为什么在Action中,最后一句几乎总是mapping.findForward("xxx");了。因为我们在这个Action中设置的请

求作用域的变量都将会在下一个页面(也许是另一个Action)中用到,所以要用转发。

总结:
用重定向和转发不是一个习惯问题。而是什么情况下必须用什么的问题。
不要仅仅为了把变量传到下一个页面而使用session作用域,那会无故增大变量的作用域,转发也许可以帮助你解决这个问题。
重定向:以前的request中存放的变量全部失效,并进入一个新的request作用域。
转发:以前的request中存放的变量不会失效,就像把两个页面拼到了一起。

### ### 概念区别 在 HTTP 协议中,**转发(Forward)****重定向(Redirect)**是两种不同的请求处理机制。它们的主要区别在于请求的处理流程、客户端是否感知以及数据传递方式等方面。 转发是一种服务器内部的操作,指服务器接收到请求后,将该请求委托给其他资源(如 Servlet、JSP 等)进行处理,整个过程在服务器端完成。对于客户端而言,这一操作是透明的,客户端并不知道请求被转发到了其他资源。这种机制通常使用 `RequestDispatcher` 的 `forward()` 方法实现,在 Java Web 应用中较为常见[^4]。 与之不同的是,重定向是服务器通过发送特定的 HTTP 响应码(如 301、302)响应头中的 `Location` 字段,告知客户端需要重新发起一个新的请求到另一个 URL。客户端会收到重定向的指令,并根据新的 URL 再次发送请求。因此,重定向涉及两次独立的 HTTP 请求/响应交互。 ### ### 实现原理对比 在转发过程中,服务器将原始请求响应对象传递给目标资源,目标资源处理完成后将结果返回给服务器,再由服务器将响应返回给客户端。由于整个过程是在服务器端完成的,客户端浏览器地址栏显示的 URL 不会发生变化。 而重定向则是基于客户端行为实现的。当服务器决定执行重定向时,它不会直接返回最终内容,而是返回一个状态码新 URL。客户端浏览器接收到响应后,会自动向新的 URL 发起第二次请求,此时浏览器地址栏会更新为重定向后的 URL[^4]。 ### ### 数据传递方式 转发可以通过 `request` 对象携带属性信息,这些信息在整个请求范围内有效,因此目标资源可以获取到转发前设置的数据。这种方式适用于需要多个组件协作处理同一个请求的场景,例如权限验证之后转发到业务逻辑页面[^4]。 相比之下,重定向无法直接通过 `request` 对象传递数据,因为它是两个独立的请求。为了在重定向前后传递信息,通常采用 URL 参数、Cookie 或者 Session 的方式进行数据交换。例如,在 OAuth 授权流程中,服务端常常使用 `state` 参数来防止 CSRF 攻击,并确保请求来自原始发起方[^1]。 ### ### 用户体验差异 转发对用户是不可见的,浏览器地址栏始终显示最初请求的 URL,因此用户感知不到服务器内部的处理流程。而重定向会导致浏览器地址栏发生变化,用户可以看到跳转的过程,并且可以根据新 URL 直接访问目标资源。这也意味着重定向具有更强的可书签性(bookmarkable),适合用于资源移动或页面跳转等场景。 ### ### 使用场景示例 转发常用于将一个请求分发给不同的组件进行处理。例如在一个 Web 应用中,将用户登录请求先由一个 Servlet 进行初步验证,然后转发给另一个 Servlet 进行具体的业务逻辑处理,这样可以保持 URL 的一致性并减少网络往返次数。 重定向则多用于用户登录成功后跳转到首页、资源移动到新的 URL 后需要引导用户访问新地址等场景。例如,用户注册成功后,重定向到登录页面让用户进行登录操作,或者在支付完成后跳转至订单详情页。此外,重定向也常用于防止表单重复提交,通过 PRG(Post/Redirect/Get)模式实现幂等性[^4]。 ### 示例代码 以下是一个简单的 Java Servlet 示例,展示转发重定向的不同效果: ```java // 转发示例 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("message", "This is a forwarded message."); RequestDispatcher dispatcher = request.getRequestDispatcher("/target.jsp"); dispatcher.forward(request, response); } // 重定向示例 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { String redirectUrl = "https://example.com/new-location"; response.sendRedirect(redirectUrl); } ``` 在上述代码中,转发使用了 `RequestDispatcher.forward()` 方法,保留了原始请求上下文;而重定向通过 `HttpServletResponse.sendRedirect()` 方法触发客户端的新请求。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值