【javaWeb】sendRedirect和forward原理及区别总结

来源:互联网 发布:淘宝店铺转让价格表 编辑:程序博客网 时间:2024/06/06 08:13
一、原理. 
1、 Forward 
 
 

 
该图的交互过程如下:
 浏览器访问Servlet1。
 Servlet1想让Servlet2对客户端的请求进行响应,于是调用forward()方法,将请求转发给Servlet2进行处理。
 Servlet2对请求做出响应。
交互过程可以看出,调用forward()方法,对浏览器来说是透明的,浏览器并不知道为其服务的Servlet已经换成Servlet2了,它只知道发出了一个请求,获得了一个响应。显示的URL始终是原始请求的URL。
sendRedirect()方法和forward()方法还有一个区别,那就是sendRedirect()方法不但可以在位于同一主机上的不同Web应用程序之间进行重定向,而且可以将客户端重定向到其他服务器上的Web应用程序资源。
 

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

(1)当对来自client的request处理完,并把所有数据输出到缓冲区 
(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
Html代码  
  1. <span style="font-size: medium;"><%@ page language="java" import="java.util.*" pageEncoding="GBK"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  7. <html>  
  8.   <head>  
  9.     <base href="<%=basePath%>">  
  10.     <title>My JSP 'end.jsp' starting page</title>  
  11.  <meta http-equiv="pragma" content="no-cache">  
  12.  <meta http-equiv="cache-control" content="no-cache">  
  13.  <meta http-equiv="expires" content="0">      
  14.  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  15.  <meta http-equiv="description" content="This is my page">  
  16.  <!-- 
  17.  <link rel="stylesheet" type="text/css" href="styles.css"> 
  18.  -->  
  19.   </head>  
  20.   <body>  
  21.    name:${param.name}, sex:${requestScope.sex}, the end page!  
  22.   </body>  
  23. </html>  
  24. </span>  
 
 
 
 first2.jsp
Html代码  
  1. <span style="font-size: medium;"> <%@ page language="java" import="java.util.*" pageEncoding="GBK"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  7. <html>  
  8.   <head>  
  9.     <base href="<%=basePath%>">  
  10.     <title>My JSP 'first.jsp' starting page</title>  
  11.  <meta http-equiv="pragma" content="no-cache">  
  12.  <meta http-equiv="cache-control" content="no-cache">  
  13.  <meta http-equiv="expires" content="0">      
  14.  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  15.  <meta http-equiv="description" content="This is my page">  
  16.  <!-- 
  17.  <link rel="stylesheet" type="text/css" href="styles.css"> 
  18.  -->  
  19.   </head>  
  20.   <body>  
  21.     This is my JSP page. <br>  
  22.     <%  
  23.     request.setAttribute("sex", "man");  
  24.    <span style="color: #0000ff;"> response.sendRedirect("/studyProject/myforward/end2.jsp");//绝对路径</span>  
  25.     %>  
  26.   </body>  
  27. </html>  
  28. </span>  
 
 
 
 
结果:
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
Html代码  
  1. <span style="font-size: medium;"><%@ page language="java" import="java.util.*" pageEncoding="GBK"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  7. <html>  
  8.   <head>  
  9.     <base href="<%=basePath%>">  
  10.     <title>My JSP 'first.jsp' starting page</title>  
  11.  <meta http-equiv="pragma" content="no-cache">  
  12.  <meta http-equiv="cache-control" content="no-cache">  
  13.  <meta http-equiv="expires" content="0">      
  14.  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  15.  <meta http-equiv="description" content="This is my page">  
  16.  <!-- 
  17.  <link rel="stylesheet" type="text/css" href="styles.css"> 
  18.  -->  
  19.   </head>  
  20.   <body>  
  21.     This is my JSP page. <br>  
  22.     <%  
  23.     request.setAttribute("sex", "man");  
  24.     %>  
  25. <span style="color: #0000ff;">    <jsp:forward page="/myforward/end.jsp"></span>  
  26.       <jsp:param value="tomzhang" name="name"/>  
  27.     </jsp:forward>  
  28.   </body>  
  29. </html>  
  30. </span>  
 
 
 
end.jsp
 
Html代码  
  1. <span style="font-size: medium;"><%@ page language="java" import="java.util.*" pageEncoding="GBK"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  7. <html>  
  8.   <head>  
  9.     <base href="<%=basePath%>">  
  10.     <title>My JSP 'end.jsp' starting page</title>  
  11.  <meta http-equiv="pragma" content="no-cache">  
  12.  <meta http-equiv="cache-control" content="no-cache">  
  13.  <meta http-equiv="expires" content="0">      
  14.  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  15.  <meta http-equiv="description" content="This is my page">  
  16.  <!-- 
  17.  <link rel="stylesheet" type="text/css" href="styles.css"> 
  18.  -->  
  19.   </head>  
  20.   <body>  
  21.    name:${param.name}, sex:${requestScope.sex}, the end page!  
  22.   </body>  
  23. </html>  
  24. </span>  
 
 结果:
name:tomzhang, sex:man, the end page! 
url一直保持不变 http://localhost:8080/studyProject/myforward/first.jsp

注:本来转载自51CTO.COM
 
0 0