`
JavaCrazyer
  • 浏览: 3012281 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类

sendRedirect和forward原理及区别总结

阅读更多

一、原理. 
1
 Forward 

 

 

 

该图的交互过程如下:

浏览器访问Servlet1

Servlet1想让Servlet2对客户端的请求进行响应,于是调用forward()方法,将请求转发给Servlet2进行处理。

Servlet2对请求做出响应。

交互过程可以看出,调用forward()方法,对浏览器来说是透明的,浏览器并不知道为其服务的Servlet已经换成Servlet2了,它只知道发出了一个请求,获得了一个响应。显示的URL始终是原始请求的URL

sendRedirect()方法和forward()方法还有一个区别,那就是sendRedirect()方法不但可以在位于同一主机上的不同Web应用程序之间进行重定向,而且可以将客户端重定向到其他服务器上的Web应用程序资源。

 


      
这种方式是在服务器端作的重定向。服务器往client发送数据的过程是这样的:服务器在向客户端发送数据之前,是先将数据输出到缓冲区,然后将缓冲区中数据发送给client端。什么时候将缓冲区里的数据发送给client端呢? 

1)当对来自clientrequest处理完,并把所有数据输出到缓冲区
 
2)当缓冲区满
 
3)在程序中调用缓冲区的输出方法out.flush()response.flushbuffer()web container才将缓冲区中的数据发送给client
 

      
这种重定向方式是利用服务器端的缓冲区机制,在把缓冲区的数据发送到客户端之前,原来的数据不发送,将执行转向重定向页面,发送重定向页面的数据,重定向调用页的数据将被清除。如果在<JSP:FORWORD>之前有很多输出,前面的输出已使缓冲区满,将自动输出到客户端,那么这种重定向方式将不起作用,这一点应该特别注意。
 

public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException 

response.setContentType("text/html; charset=UTF-8"); 
ServletContext sc = getServletContext(); 
RequestDispatcher rd = null; 
rd = sc.getRequestDispatcher("/index.jsp"); 
rd.forward(request, response); 


2
 sendRedirect 

 

 

 

交互过程可以看出,调用sendRedirect()方法,实际上是告诉浏览器Servlet2所在的位置,让浏览器重新访问Servlet2。调用sendRedirect()方法,会在响应中设置Location响应报头。要注意的是,这个过程对于用户来说是透明的,浏览器会自动完成新的访问。浏览器的地址栏中,可以看到,显示的URL是重定向之后的URL

该图的交互过程如下:

浏览器访问Servlet1

Servlet1想让Servlet2为客户端服务。

Servlet1调用sendRedirect()方法,将客户端的请求重定向到Servlet2

浏览器访问Servlet2

Servlet2对客户端的请求做出响应。

 


      

这种方式是在客户端作的重定向处理。该方法通过修改HTTP协议的HEADER部分,对浏览器下达重定向指令的,让浏览器对在location中指定的URL提出请求,使浏览器显示重定向网页的内容。该方法可以接受绝对的或相对的URLs。如果传递到该方法的参数是一个相对的URL,那么Web container在将它发送到客户端前会把它转换成一个绝对的URL 

public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException 

response.setContentType("text/html; charset=UTF-8"); 
response.sendRedirect("/index.jsp"); 
}

 

二、区别

 

1.response.sendRedirect(url)

1)重定向,不转发请求,地址栏的url已改变

2)request.getAttribute(""),request.getParamter("")都获取不了 

response.sendRedirect("/studyProject/myforward/end2.jsp?name=tomzhang");//可以带参数的

   例子

   end2.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'end.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->
  </head>
  <body>
   name:${param.name}, sex:${requestScope.sex}, the end page!
  </body>
</html>

 

 

 

 first2.jsp

 <%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'first.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->
  </head>
  <body>
    This is my JSP page. <br>
    <%
    request.setAttribute("sex", "man");
    response.sendRedirect("/studyProject/myforward/end2.jsp");//绝对路径
    %>
  </body>
</html>

 

 

 

 

结果:
name:, sex:, the end page!
url变成
http://localhost:8080/studyProject/myforward/end2.jsp

 


2.<jsp:forward page="" />

1)请求转发,地址栏的url不变

2)可以传递额外的参数

<jsp:param name="" value=""/>

3)request.getAttribute("");//基于请求的request共享

request.getParamter("");//请求转发

4)等同requestDispatcher.forward(url); 

<jsp:forward page="/myforward/end.jsp?age=man">//可以带参数

*使用forward一定要注意url页面的链接,不要使用相对路径;url页面的当前路径其实是第1次请求时的当前路径,所以url页面的链接都应该采用绝对路径!

例子:
first.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'first.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->
  </head>
  <body>
    This is my JSP page. <br>
    <%
    request.setAttribute("sex", "man");
    %>
    <jsp:forward page="/myforward/end.jsp">
      <jsp:param value="tomzhang" name="name"/>
    </jsp:forward>
  </body>
</html>

 

 

 

end.jsp

 

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'end.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->
  </head>
  <body>
   name:${param.name}, sex:${requestScope.sex}, the end page!
  </body>
</html>

 

 结果:
name:tomzhang, sex:man, the end page!
url一直保持不变
http://localhost:8080/studyProject/myforward/first.jsp

 

 

 

三、详解

 1. 跳转方式
http://localhost:8080/Test应用
运用forward方法只能重定向到同一个Web应用程序中的一个资源。而sendRedirect方法可以让你重定向到任何URL。
表单form的action= "/uu ";sendRedirect( "/uu ");表示相对于服务器根路径。如
http://localhost:8080/Test应用(则提交至http://localhost:8080/uu);
Forward代码中的 "/uu "则代表相对与WEB应用的路径。如
http://localhost:8080/Test应用(则提交至http://localhost:8080/Test/uu);
2. (运用RequestDispatcher接口的Forward)方法
forward()无法重定向至有frame的jsp文件,可以重定向至有frame的html文件,
同时forward()无法在后面带参数传递,比如servlet?name=frank,这样不行,可以程序内通过response.setAttribute( "name ",name)来传至下一个页面.
重定向后浏览器地址栏URL不变. 

只有在客户端没有输出时才可以调用forward方法。如果当前页面的缓冲区(buffer)不是空的,那么你在调用forward方法前必须先清空缓冲区。
"/ "代表相对与web应用路径 

RequestDispatcher   rd   =   request.getRequestDispatcher( "/ooo ");
rd.forward(request,   response);提交至
http://localhost:8080/Test/ooo 

RequestDispatcher   rd   =   getServletContext().getRequestDispatcher( "/ooo ");
rd.forward(request,   response);提交至
http://localhost:8080/Test/ooo 

RequestDispatcher   rd   =getServletContext().getNamedDispatcher( "TestServlet ");(TestServlet为一个 <servlet-name> )
rd.forward(request,   response);提交至名为TestServlet的servlet 

如果在 <jsp:forward> 之前有很多输出,前面的输出已使缓冲区满,将自动输出到客户端,那么该语句将不起作用,这一点应该特别注意。
另外要注意:它不能改变浏览器地址,刷新的话会导致重复提交
http://localhost:8080/Test/gw/page.jsp中转发
<jsp:forward   page= "OtherPage.jsp "/> 在JSP页面被解析后转换成pageContext.forward( "OtherPage.jsp ");
"/OtherPage.jsp "提交到
http://localhost:8080/Test/OtherPage.jsp
"OtherPage.jsp "提交到
http://localhost:8080/Test/gw/OtherPage.jsp 


(运用HttpServletResponse接口的sendRedirect)方法302
是在用户的浏览器端工作,sendRedirect()可以带参数传递,比如servlet?name=frank传至下个页面,
同时它可以重定向至不同的主机上,sendRedirect()可以重定向有frame.的jsp文件.

假设转发代码包含于注册的servlet-url为/ggg/tt;jsp为/ggg/tt.jsp:
绝对路径:response.sendRedirect( "
http://www.brainysoftware.com ")发送至http://www.brainysoftware.com
根路径:response.sendRedirect( "/ooo ")发送至
http://localhost:8080/ooo
相对路径:response.sendRedirect( "ooo ")发送至
http://localhost:8080/Test/ggg/ooo,

sendRedirect等同于此方式
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
String   newLocn   =   "/newpath/jsa.jsp ";
response.setHeader( "Location ",newLocn);

 


(Meta   Refresh)方法200
这种方法是由HTML提供的,Meta本身就是HTML标签。使用方法是: <meta   http-equiv= "refresh "   content= "5;   url=http://www.dreamdu.com/ "   />
相应的java代码
String   content=stayTime+ ";URL= "+URL;
response.setHeader( "REFRESH ",content);
3. 使用response.sendRedirect()地址栏将改变
使用request.getRequestDispatcher().forward(request,response)地址栏中的信息保持不变
4. request.setAttribute存的东西

只用通过方法2跳转   才能在新页取出来
5. redirect   会首先发一个response给浏览器,   然后浏览器收到这个response后再发一个requeset给服务器,   然后服务器发新的response给浏览器.   这时页面收到的request是一个新从浏览器发来的.
forward   发生在服务器内部,   在浏览器完全不知情的情况下发给了浏览器另外一个页面的response.   这时页面收到的request不是从浏览器直接发来了,可能己经放了数据.
所以: request.setAttribute存的东西
        只用通过方法2跳转   才能在新页取出来
 

 

 

 

 

 

本文图片和部分段落来自网络

  • 大小: 14.2 KB
  • 大小: 12.3 KB
3
3
分享到:
评论

相关推荐

    forward PK sendredirect

    在Web开发中,"forward"和"sendRedirect...总结来说,`jsp:forward`和`response.sendRedirect`各有优势,选择哪种方式取决于具体的需求和场景。理解它们的工作原理和差异,可以帮助我们更合理地设计Web应用程序的流程。

    forward-sendRedirect

    总结一下,`forward()`和`sendRedirect()`是Java Web开发中处理页面跳转的两种主要方式。`forward()`在不生成新请求的情况下传递请求状态,适合于内部跳转;`sendRedirect()`通过生成新请求实现跳转,适用于防止重复...

    Java Web应用开发 15 课堂案例-使用forward动作.docx

    我们将深入探讨这个案例的各个部分,以便更好地了解`jsp:forward`的工作原理和应用场景。 首先,`jsp:forward`动作的基本语法是`&lt;jsp:forward page="relativeURL"/&gt;`,其中`relativeURL`参数是相对于当前页面的URL...

    idea做一个带有验证码的登录界面,包函forword转发和sendRedirect重定向方法

    首先,让我们了解一下`forward`和`redirect`的区别: 1. **`forward`(转发)**: - `forward`是服务器内部操作,它不会改变浏览器地址栏中的URL。当服务器接收到请求后,可以将请求转发到另一个资源,如JSP页面,...

    JSP页面跳转方法总结

    `RequestDispatcher`类同样提供了服务器端内部转发的功能,其实现原理与`forward`动作标记相似。但需要注意的是,`RequestDispatcher`支持更多的功能,如指定绝对路径等。 示例: ```java RequestDispatcher rd = ...

    JSP重定向技巧

    本文将深入探讨JSP中的重定向技巧,包括服务器端重定向和客户端重定向,并分析它们的工作原理及适用场景。 首先,我们来看JSP页面重定向的三种主要方法: 1. 使用`response.sendRedirect()`方法,这是客户端重定向...

    java面试时候经常会问的一些问题.doc

    2. response.sendRedirect() 和 forward() 区别? response.sendRedirect() 用于重定向到一个新的 URL,而 forward() 用于将请求转发到一个新的 URL。 3. &lt;%@include file="xxx.jsp"%&gt; 和 &lt;jsp:include&gt; 区别? %...

    小结jsp页面跳转问题

    通过本文档,我们将深入探讨几种常用的JSP页面跳转方式:`response.sendRedirect()`、`response.setHeader()`以及`&lt;jsp:forward&gt;`指令,并通过具体的示例代码来解析这些方法的工作原理及注意事项。 #### 一、`...

    请求转发和重定向的区别共1页.pdf.zip

    在Web开发中,请求转发和重定向是两种常见的服务器端处理客户端请求的技术,它们虽然都是用来改变客户端浏览器的页面展示,但实现机制和效果却...理解它们的工作原理和差异,对于优化网站性能和提升用户体验至关重要。

    java变态面试题.pdf

    * forward 与 sendRedirect 的区别:forward 是服务器端的跳转,而 sendRedirect 是客户端的跳转。 四、框架知识点 * Spring 框架:管理实体 Bean,AOP 是什么?通常用来干些什么? * Struts1 和 Struts2 的区别:...

    servlet知识点(手动收集)

    - `forward()` 方法可以在服务器内部保留原始请求和响应对象,因此在跳转过程中可以轻松地将参数从一个页面传递到另一个页面。 - 可以通过 `request.setAttribute(String name, Object obj)` 来设置属性,然后在...

    jsp页面跳转

    它的工作原理类似于 `RequestDispatcher.forward()`,但在实现上更为简洁。 **实现原理:** `&lt;jsp:forward&gt;` 标签本质上是调用 `RequestDispatcher.forward()` 来完成页面跳转的。该标签会将当前请求转发到指定的...

    Java面试题完整版(含参考答案).doc

    总结来说,理解Java中的抽象类与接口、EJB与JavaBean的异同,以及Servlet API中转发与重定向的原理,是Java开发者必备的知识点,这些概念和方法在实际开发中有着广泛的应用。熟练掌握这些内容不仅有助于通过面试,更...

    jsp页面跳转的五中方法

    `&lt;jsp:forward page="" /&gt;`是JSP页面中的一种简便的跳转方式,其实现原理与`RequestDispatcher.forward()`相似,也是服务器端的跳转。这种方式同样可以传递请求参数到目标页面。 **示例代码:** ```jsp &lt;jsp:...

    传智播客 赖家才老师 主讲 struts1 的课堂总结

    赖家才老师的课堂总结深入浅出地讲解了Struts1的核心概念和使用技巧,帮助我们理解这个框架的工作机制。 1. **Action 初始化**: - Action 对象在每次请求时初始化,而不是在配置加载时初始化。这意味着每个请求...

    java web知识集锦.doc

    本文将深入探讨`RequestDispatcher`和`sendRedirect()`之间的主要区别,并通过实例帮助理解如何在实际项目中正确使用这两种技术。 #### RequestDispatcher详解 `RequestDispatcher`接口提供了在服务器端进行请求...

    servlet jsp总结

    ### Servlet与JSP知识点总结 #### 一、Servlet概述及基本使用 ...Servlet通常作为MVC架构模式中的控制器...通过上述知识点的梳理,我们可以更深入地理解Servlet和JSP的工作原理以及如何有效地利用它们构建Web应用程序。

    JSP中5种跳转的方法

    除了 `forward()` 和 `sendRedirect()` 方法之外,还可以利用 `RequestDispatcher` 来实现值栈的跳转。这种跳转方式通常是在需要保持上下文信息的同时进行页面跳转。 #### 使用场景 - 当需要在跳转过程中保留一些...

Global site tag (gtag.js) - Google Analytics