JSP/Servlet转发与重定向的区别

 尽管HttpServletResponse.sendRedirect 方法和RequestDispatcher.forward 方法都可以让浏览器获得另外一个URL所指向的资源,但两者的内部运行机制有着很大的区别。

        下面是HttpServletResponse.sendRedirect 方法实现的请求重定向与RequestDispatcher.forward 方法实现的请求转发的总结比较:

        (1)RequestDispatcher.forward 方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。如果传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果创建RequestDispatcher 对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。

        (2)调用HttpServletResponse.sendRedirect 方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;而调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。

        (3)HttpServletResponse.sendRedirect 方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求。

        举个例子:重定向过程好比有个绰号叫“浏览器”的人写信找张三借钱,张三回信说没有钱,让“浏览器”去找李四借,并将李四现在的通信地址告诉给了“浏览器”。于是,“浏览器”又按张三提供通信地址给李四写信借钱,李四收到信后就把钱汇给了“浏览器”。可见,“浏览器”一共发出了两封信和收到了两次回复,“浏览器”也知道他借到的钱出自李四之手。 RequestDispatcher.forward 方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程好比绰号叫“浏览器”的人写信找张三借钱,张三没有钱,于是张三找李四借了一些钱,甚至还可以加上自己的一些钱,然后再将这些钱汇给了“浏览器”。可见,“浏览器”只发出了一封信和收到了一次回复,他只知道从张三那里借到了钱,并不知道有一部分钱出自李四之手。 

        (4)RequestDispatcher.forward 方法的调用者与被调用者之间共享相同的request 对象和response 对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect 方法调用者与被调用者使用各自的request 对象和response 对象,它们属于两个独立的访问请求和响应过程。 

        对于同一个WEB应用程序的内部资源之间的跳转,特别是跳转之前要对请求进行一些前期预处理,并要使用HttpServletRequest.setAttribute 方法传递预处理结果,那就应该使用RequestDispatcher.forward 方法。 

        不同WEB应用程序之间的重定向,特别是要重定向到另外一个WEB站点上的资源的情况,都应该使HttpServletResponse.sendRedirect 方法。 

        (5)无论是RequestDispatcher.forward 方法,还是HttpServletResponse.sendRedirect 方法,在调用它们之前,都不能有内容已经被实际输出到了客户端。如果缓冲区中已经有了一些内容,这些内容将被从缓冲区中清除。

对比指标  请求转发  重定向
Servlet中的使用方法  <jsp:forward page="new.jsp" />  <%response.sendRedirect("new.jsp");
jsp中的使用方法

 RequestDispatcher rd = request.getRequestDispatcher(path);
 rd.forward(request,response);

 response.sendRedirect(path);
意义  请求转发到另一资源  页面重新定向到某个新地址,之前的请求失效,进入一个新请求
浏览器地址  浏览器地址栏地址不变  浏览器地址栏地址改变
定义  服务器端跳转  客户端跳转
请求次数  向服务器请求一次(request)  向服务器请求两次:1、向服务器申请响应码;2、带着响应码向服务器请求(request只在第一次有效,在第二次请求时已被销毁)。
请求对象  调用者和被调用者共享同一个request和response对象  调用者和被调用者使用各自的request和response
请求资源的范围  只能将请求转发给同一个web中应用中的组件  不仅可以重定向到当前应用的其他资源,还可以重定向到其他站点的资源
请求转发 请求重定向 包含
1、请求转发

   请求转发允许把请求转发给同一应用程序中的其他Web组件。这种技术通常用于Web应用控制层的Servlet流程控制器,它检查HTTP请求数据,并将请求转发到合适的目标组件,目标组件执行具体的请求处理具体的请求处理操作,并生成响应结果。


Servlet类使用javax.servlet.RequestDispatcher.forward()方法来转发它所收到的HTTP请求。转发目标组件将处理该请求并生成响应结果,或者将请求继续转发到另一个组件。最初请求的ServletRequest和ServletResponse对象被传递给转发目标组件,这使得目标组件可以访问整个请求上下文。值得注意的是,只能把请求转发给同一Web应用中的组件,而不能转发给其他Web应用的组件。
   如果当前的Servlet组件要把请求转发给一个JSP组件,如hello.jsp,可以在Servlet的service()方法中执行以下代码:
         RequestDispatcher rd = request.getRequestDispatcher("hello.jsp");
         //Forward to requested URL
         rd.forward(request, response);
   在JSP页面中,可以使用<jsp:forward>标签来转发请求,例如:
         <jsp:forward page="hello.jsp">
   对于请求转发,转发的源组件和目标组件共享request范围内的共享数据。
2、URL重定向
   请求重定向类似于请求转发,但也有一些重要区别:
Web组件可以将请求重定向到任一URL,而不仅仅是同一应用中的URL。
重定向的源组件和目标组件之间不共用同一个HttpServletRequest对象,因此不能共享request范围内的共享数据。


如果当前应用的Servlet组件要把请求转发给URL"http://jakarta.apache.org/struts",可以在Servlet的service()方法中执行以下代码:
response.sendRedirect("http://jakarta.apache.org/struts");
   HttpServletResponse的sendRedirect()方法向浏览器返回包含重定向的信息,浏览器根据这一信息迅速发出一个新HTTP请求,请求访问重定向目标组件。
3、包含
   包含关系允许一个Web组件聚集来自同一个应用中其他Web组件的输出数据,并使用被聚集的数据来创建响应结果。这种技术通常用于模板处理器,它可以控制网页的布局。模板中每个页面区域的内容来自不同的URL,从而组成单个页面。这种技术能够为应用程序提供一致的外观和感觉。包含关系的源组件和目标组件共用同一个HttpServletRequest对象,因此它们共享request范围内的共享数据。


Servlet类使用javax.servlet.RequestDispatcher.include()方法包含其他的Web组件。例如,如果当前的Servlet组件包含了三个JSP文件:header.jsp、main.jsp和footer.jsp,则可以在Servlet的service()方法中执行以下代码:
RequestDispatcher rd;
rd = req.getRequestDispatcher("/header.jsp")
rd.include(req,res);
rd = req.getRequestDispatcher("/main.jsp")
rd.include(req,res);
rd = req.getRequestDispatcher("/footer.jsp")
rd.include(req,res);
   在JSP文件中,可以通过<include>指令来包含其他的Web资源,例如:
<%@ include file="header.jsp"%>
<%@ include file="main.jsp"%>
<%@ include file="footer.jsp"%>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值